/* val5.c  2013-04-02 10:00
   Reference executable for validating application profiling tools.
   val5:  recursive function with one self-invocation.

   With default values of FN1LOOP and FN2LOOP, the expected distribution of
   time is 100 % to cycfn, of which 33 % is in the first (top) invocation and
   66 % is in the second (leaf) invocation.

   Language -std=gnu99 (with gcc-specific attributes).
   Original versions tested:  gcc 4.7.2.
*/

// Configurable FN1LOOP:  how many busy-work iterations in top invocation.
#ifndef FN1LOOP
#define FN1LOOP 100000000
#endif

// Configurable FN2LOOP:  how many busy-work iterations in leaf invocation.
#ifndef FN2LOOP
#define FN2LOOP (FN1LOOP*2)
#endif

#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdbool.h>

uint64_t accumulator=1;
double   adder=0;

__attribute__((noinline,optimize("no-optimize-sibling-calls")))
void cycfn (bool leaf) {
  for (uint64_t looper=0; looper<(leaf ? FN2LOOP : FN1LOOP); ++looper)
    adder += M_PI*3, accumulator = accumulator*3 + adder;
  if (!leaf)
    cycfn (true);
}

int main() {
  cycfn (false);
  printf ("%" PRIu64 " %f\n", accumulator, adder);
  return 0;
}
