- double next_chunk;
- double remains;
- int i;
- long index;
- int top_level;
- double b;
- int done;
- long l_bounds[TRACE_NB_LEVELS]; /* May be too bgi for this trace */
- double a_divided_by_spacing;
- double current_spacing;
-
- DEBUG2("Solving simple integral [x=%.2f,amount=%.2f]", a, amount);
-
- /* Sanity checks */
- if ((a < 0.0) || (amount < 0.0) || (a > trace->last_time)) {
- CRITICAL2
- ("Error, invalid parameters [a = %.2f, amount = %.2f]. You probably have a task executing with negative computation amount. Check your code.",
- a, amount);
- xbt_abort();
- }
- if (amount == 0.0) {
- /* fprintf(stderr,"Warning: trivial integral solve\n"); */
- return a;
- }
-
- for (i = 0; i < trace->nb_levels; i++) {
- a_divided_by_spacing = a / trace->levels[i]->spacing;
- if (ceil(a_divided_by_spacing) == a_divided_by_spacing)
- l_bounds[i] = 1 + (long) ceil(a_divided_by_spacing);
- else
- l_bounds[i] = (long) (ceil(a_divided_by_spacing));
-
- if ((l_bounds[i] + 1) * trace->levels[i]->spacing > trace->last_time)
- break;
-
- DEBUG2("level %d: l%ld", i, l_bounds[i]);
- }
- if (i == trace->nb_levels)
- top_level = trace->nb_levels - 1;
- else {
- top_level = i;
- }
-
- remains = amount;
- /* first sub-level amount */
- next_chunk = ((l_bounds[0]) * (trace->levels[0]->spacing) - a) *
- (trace->levels[0]->values[l_bounds[0] - 1]);
-
- if (remains - next_chunk < 0.0) {
- b = a + (amount / trace->levels[0]->values[l_bounds[0] - 1]);
-
- DEBUG1("Returning sub-level[0] result %.2f", b);
-
- return b;
- } else {
- b = (l_bounds[0]) * (trace->levels[0]->spacing);
- remains -= next_chunk;
- }
- DEBUG2("After sub-0 stuff: remains %.2f (b=%.2f)", remains, b);
-
- /* first n-1 levels */
- DEBUG0("Going up levels");
-
- done = 0;
- for (i = 0; i < top_level; i++) {
-
- current_spacing = trace->levels[i]->spacing;
- index = l_bounds[i];
-
- DEBUG1("L%d:", i);
-
- while (double_positive
- (l_bounds[i + 1] * trace->levels[i + 1]->spacing -
- index * current_spacing)
- && ((index + 1) * (current_spacing) < trace->last_time)) {
-
- next_chunk = current_spacing * trace->levels[i]->values[index];
-
- DEBUG3("%.2f next_chunk= %.2f remains=%.2f",
- (index + 1) * (trace->levels[i]->spacing), next_chunk, remains);
-
- if (remains - next_chunk < 0.0) { /* Too far */
- done = 1;
- break;
- } else { /* Keep going */
- DEBUG2("%.2f->%.2f|",
- index * (trace->levels[i]->spacing),
- (index + 1) * (trace->levels[i]->spacing));
-
- remains -= next_chunk;
- b = (index + 1) * (current_spacing);
- }
- index++;
- }
- if (done) {
- /* found chunk, fix the index to top level */
- i++;
- break;
- }
- }
-
- DEBUG0("Steady");
- top_level = i;
-
- /* n-th level */
- current_spacing = trace->levels[top_level]->spacing;
- index = l_bounds[top_level];
-
- DEBUG1("L%d:", top_level);
-
- /* iterate over the last level only if it hasn't found the chunk where the amount is */
- if (!done) {
- while (index < trace->levels[top_level]->nb_points) {
- next_chunk = current_spacing * trace->levels[top_level]->values[index];
- if (remains - next_chunk <= 0.0) { /* Too far */
- break;
- } else {
- DEBUG2("%.2f->%.2f|",
- index * (trace->levels[top_level]->spacing),
- (index + 1) * (trace->levels[top_level]->spacing));
-
- remains -= next_chunk;
- b = (index + 1) * (current_spacing);
- }
- index++;
- }
- }
- DEBUG2("remains = %.2f b=%.2f", remains, b);
-
- /* And going back down */
- DEBUG0("Going back down");
- for (i = top_level - 1; i >= 0; i--) {
-
- current_spacing = trace->levels[i]->spacing;
- index = b / (trace->levels[i]->spacing);
-
- DEBUG1("L%d:", i);
-
- while (index < trace->levels[i]->nb_points) {
- next_chunk = current_spacing * trace->levels[i]->values[index];
- if (remains - next_chunk <= 0.0) { /* Too far */
- break;
- } else {
- DEBUG2("%.2f->%.2f|",
- index * (current_spacing), (index + 1) * (current_spacing));
-
- remains -= next_chunk;
- b += current_spacing;
- }
- index++;
- }
- }
-
- DEBUG2("remains = %.2f b=%.2f\n", remains, b);
- DEBUG1("Last bit index=%ld\n", index);
-
- /* Little piece at the end */
- b += (remains) / (trace->levels[0]->values[index]);
-
- return b;