22fcd72608e14564e7914054cbce3f8405847f08
[charm.git] / tests / converse / megacon / fibthr.c
1 #include <stdio.h>
2 #include <converse.h>
3 void Cpm_megacon_ack();
4
5 /* an accumulator datatype, which can have one pending thread */
6
7 #define STACKSIZE_DEFAULT 0
8
9 typedef struct accum
10 {
11   int total; int countdown;
12   CthThread pending;
13 }
14 *accum;
15
16 CpmDeclareSimple(accum);
17 #define CpmPack_accum(x)
18 #define CpmUnpack_accum(x)
19
20 #include "fibthr.cpm.h"
21
22 int randpe()
23 {
24   /* return ((rand()&0x7FFFFFFF)>>11) % CmiNumPes(); */
25   return ((CrnRand()&0x7FFFFFFF)>>11) % CmiNumPes();
26 }
27
28 /* a function to add a number to an accumulator */
29
30 CpmInvokable accum_add(accum a, int val)
31 {
32   a->total += val;
33   a->countdown --;
34   if ((a->countdown==0)&&(a->pending))
35     CthAwaken(a->pending);
36 }
37
38 /* The fib function: calculate fib of N, then add it to the specified accum */
39
40 CpmInvokable fibthr(int n, int pe, accum resp)
41 {
42   int result;
43   if (n<2) result = n;
44   else {
45     struct accum acc;
46     acc.total = 0; acc.countdown = 2; acc.pending = CthSelf();
47     Cpm_fibthr(CpmMakeThreadSize(randpe(),STACKSIZE_DEFAULT), n-1, CmiMyPe(), &acc);
48     Cpm_fibthr(CpmMakeThreadSize(randpe(),STACKSIZE_DEFAULT), n-2, CmiMyPe(), &acc);
49     CthSuspend();
50     result = acc.total;
51   }
52   Cpm_accum_add(CpmSend(pe), resp, result);
53 }
54
55 /* The top-level function */
56
57 CpmInvokable fibtop(int n)
58 {
59   struct accum acc;
60   acc.total = 0; acc.countdown = 1; acc.pending = CthSelf();
61   Cpm_fibthr(CpmMakeThreadSize(randpe(),STACKSIZE_DEFAULT), n, CmiMyPe(), &acc);
62   CthSuspend();
63   if (acc.total != 144) {
64     CmiPrintf("Failure in fibtop\n");
65     exit(1);
66   }
67   Cpm_megacon_ack(CpmSend(0));
68 }
69
70 void fibthr_init()
71 {
72   Cpm_fibtop(CpmMakeThreadSize(0,STACKSIZE_DEFAULT), 12);
73 }
74
75 void fibthr_moduleinit()
76 {
77   CpmInitializeThisModule();
78 }