Fixed bugs due to ckfutures declarations in c++interface.h
[charm.git] / src / ck-core / ckfutures.C
1
2 #include "ckdefs.h"
3 #include "chare.h"
4 #include "c++interface.h"
5 #include "ckfutures.top.h"
6 #include <stdlib.h>
7
8 /******************************************************************************
9  *
10  * The sequential future abstraction.
11  *
12  *****************************************************************************/
13
14 typedef struct Future_s
15 {
16   int ready;
17   void *value;
18   CthThread waiters;
19   int next; 
20 } Future;
21
22 typedef struct
23 {
24   Future *array;
25   int max;
26   int freelist;
27 }
28 FutureState;
29
30 CpvStaticDeclare(FutureState, futurestate);
31
32 static void addedFutures(int lo, int hi)
33 {
34   int i;
35   FutureState *fs = &(CpvAccess(futurestate));
36   Future *array = fs->array;
37
38   for (i=lo; i<hi; i++)
39     array[i].next = i+1;
40   array[hi-1].next = fs->freelist;
41   fs->freelist = lo;
42 }
43
44 static int createFuture()
45 {
46   FutureState *fs = &(CpvAccess(futurestate));
47   Future *fut; int handle, origsize, newsize, i;
48
49   /* if the freelist is empty, allocate more futures. */
50   if (fs->freelist == -1) {
51     fs->max = fs->max * 2;
52     fs->array = (Future*)realloc(fs->array, sizeof(Future)*(fs->max));
53     addedFutures(origsize, newsize);
54   }
55   handle = fs->freelist;
56   fut = fs->array + handle;
57   fs->freelist = fut->next;
58   fut->ready = 0;
59   fut->value = 0;
60   fut->waiters = 0;
61   fut->next = 0;
62   return handle;
63 }
64
65 static void destroyFuture(int handle)
66 {
67   FutureState *fs = &(CpvAccess(futurestate));
68   Future *fut = (fs->array)+handle;
69   fut->next = fs->freelist;
70   fs->freelist = handle;
71 }
72
73 static void *waitFuture(int handle, int destroy)
74 {
75   CthThread self = CthSelf();
76   FutureState *fs = &(CpvAccess(futurestate));
77   Future *fut = (fs->array)+handle;
78   void *value;
79
80   if (!(fut->ready)) {
81     CthSetNext(self, fut->waiters);
82     fut->waiters = self;
83     CthSuspend();
84   }
85   value = fut->value;
86   if (destroy) destroyFuture(handle);
87   return value;
88 }
89
90 static void setFuture(int handle, void *pointer)
91 {
92   CthThread t;
93   FutureState *fs = &(CpvAccess(futurestate));
94   Future *fut = (fs->array)+handle;
95   fut->ready = 1;
96   fut->value = pointer;
97   for (t=fut->waiters; t; t=CthGetNext(t))
98     CthAwaken(t);
99   fut->waiters = 0;
100 }
101
102 extern "C" void futuresModuleInit()
103 {
104   int i; Future *array;
105   CpvInitialize(FutureState, futurestate);
106   CpvAccess(futurestate).array = (Future *)malloc(10*sizeof(Future));
107   CpvAccess(futurestate).max   = 10;
108   CpvAccess(futurestate).freelist = -1;
109   addedFutures(0,10);
110 }
111
112
113 /******************************************************************************
114  *
115  *
116  *****************************************************************************/
117
118 int futureBocNum;
119
120 class FutureInitMsg : public comm_object
121 {
122   public: int x ;
123 };
124
125 extern "C" void *CRemoteCallBranchFn( int ep, void *m, int group, int processor)
126
127   void * result;
128   ENVELOPE *env = ENVELOPE_UPTR(m);
129   int i = createFuture();
130   SetRefNumber(m,i);
131   SetEnv_pe(env, CmiMyPe());
132   GeneralSendMsgBranch(ep, m, processor, -1, group);
133   result = waitFuture(i, 1);
134   return (result);
135 }
136
137 extern "C" void *CRemoteCallFn(int ep, void *m, ChareIDType *ID)
138
139   void * result;
140   ENVELOPE *env = ENVELOPE_UPTR(m);
141   int i = createFuture();
142   SetRefNumber(m,i);
143   SetEnv_pe(env, CmiMyPe());
144   SendMsg(ep, m, ID);
145   result = waitFuture(i, 1);
146   return (result);
147 }
148
149 class FutureBOC: public groupmember
150 {
151 public:
152
153   FutureBOC(FutureInitMsg *m) 
154   {
155   }
156   void SetFuture(FutureInitMsg * m)
157   {
158     int key;
159     key = GetRefNumber(m);
160     setFuture( key, m);
161   }
162 };
163
164 extern "C" void futuresCreateBOC()
165 {
166   FutureInitMsg *message2 = new (MsgIndex(FutureInitMsg)) FutureInitMsg ;
167   futureBocNum = new_group (FutureBOC, message2);
168 }
169
170 extern "C" void CSendToFuture(void *m, int processor)
171 {
172   CSendMsgBranch(FutureBOC, SetFuture, m, futureBocNum, processor);
173 }
174
175
176 #include "ckfutures.bot.h"