Removed almost all warnings on origin2000.
[charm.git] / src / ck-core / ckfutures.C
1 #include "charm++.h"
2 #include "ck.h"
3 #include "ckfutures.h"
4 #include <stdlib.h>
5
6 /******************************************************************************
7  *
8  * The sequential future abstraction.
9  *
10  *****************************************************************************/
11
12 typedef struct Future_s {
13   int ready;
14   void *value;
15   CthThread waiters;
16   int next; 
17 } Future;
18
19 typedef struct {
20   Future *array;
21   int max;
22   int freelist;
23 }
24 FutureState;
25
26 CpvStaticDeclare(FutureState, futurestate);
27
28 static void addedFutures(int lo, int hi)
29 {
30   int i;
31   FutureState *fs = &(CpvAccess(futurestate));
32   Future *array = fs->array;
33
34   for (i=lo; i<hi; i++)
35     array[i].next = i+1;
36   array[hi-1].next = fs->freelist;
37   fs->freelist = lo;
38 }
39
40 static int createFuture()
41 {
42   FutureState *fs = &(CpvAccess(futurestate));
43   Future *fut; int handle, origsize;
44
45   /* if the freelist is empty, allocate more futures. */
46   if (fs->freelist == -1) {
47     origsize = fs->max;
48     fs->max = fs->max * 2;
49     fs->array = (Future*)realloc(fs->array, sizeof(Future)*(fs->max));
50     addedFutures(origsize, fs->max);
51   }
52   handle = fs->freelist;
53   fut = fs->array + handle;
54   fs->freelist = fut->next;
55   fut->ready = 0;
56   fut->value = 0;
57   fut->waiters = 0;
58   fut->next = 0;
59   return handle;
60 }
61
62 static void destroyFuture(int handle)
63 {
64   FutureState *fs = &(CpvAccess(futurestate));
65   Future *fut = (fs->array)+handle;
66   fut->next = fs->freelist;
67   fs->freelist = handle;
68 }
69
70 static void *waitFuture(int handle, int destroy)
71 {
72   CthThread self = CthSelf();
73   FutureState *fs = &(CpvAccess(futurestate));
74   Future *fut = (fs->array)+handle;
75   void *value;
76
77   if (!(fut->ready)) {
78     CthSetNext(self, fut->waiters);
79     fut->waiters = self;
80     CthSuspend();
81   }
82   value = fut->value;
83   if (destroy) destroyFuture(handle);
84   return value;
85 }
86
87 static void setFuture(int handle, void *pointer)
88 {
89   CthThread t;
90   FutureState *fs = &(CpvAccess(futurestate));
91   Future *fut = (fs->array)+handle;
92   fut->ready = 1;
93   fut->value = pointer;
94   for (t=fut->waiters; t; t=CthGetNext(t))
95     CthAwaken(t);
96   fut->waiters = 0;
97 }
98
99 void _futuresModuleInit(void)
100 {
101   CpvInitialize(FutureState, futurestate);
102   CpvAccess(futurestate).array = (Future *)malloc(10*sizeof(Future));
103   CpvAccess(futurestate).max   = 10;
104   CpvAccess(futurestate).freelist = -1;
105   addedFutures(0,10);
106 }
107
108
109 /******************************************************************************
110  *
111  *
112  *****************************************************************************/
113
114 CProxy_FutureBOC fBOC(0);
115
116 class FutureInitMsg : public CMessage_FutureInitMsg {
117   public: int x ;
118 };
119
120 class  FutureMain : public Chare {
121   public:
122     FutureMain(CkArgMsg *m) {
123       fBOC.ckSetGroupId(CProxy_FutureBOC::ckNew(new FutureInitMsg));
124       CkFreeMsg(m);
125     }
126 };
127
128 extern "C" 
129 void *CkRemoteBranchCall(int ep, void *m, int group, int PE)
130
131   void * result;
132   envelope *env = UsrToEnv(m);
133   int i = createFuture();
134   env->setRef(i);
135   CkSendMsgBranch(ep, m, PE, group);
136   result = waitFuture(i, 1);
137   return (result);
138 }
139
140 extern "C" 
141 void *CkRemoteNodeBranchCall(int ep, void *m, int group, int node)
142
143   void * result;
144   envelope *env = UsrToEnv(m);
145   int i = createFuture();
146   env->setRef(i);
147   CkSendMsgNodeBranch(ep, m, node, group);
148   result = waitFuture(i, 1);
149   return (result);
150 }
151
152 extern "C" 
153 void *CkRemoteCall(int ep, void *m, CkChareID *ID)
154
155   void * result;
156   envelope *env = UsrToEnv(m);
157   int i = createFuture();
158   env->setRef(i);
159   CkSendMsg(ep, m, ID);
160   result = waitFuture(i, 1);
161   return (result);
162 }
163
164 class FutureBOC: public Group {
165 public:
166   FutureBOC(FutureInitMsg *m) { delete m; }
167   void SetFuture(FutureInitMsg * m) { 
168     int key;
169     key = UsrToEnv((void *)m)->getRef();
170     setFuture( key, m);
171   }
172 };
173
174 extern "C" 
175 void CkSendToFuture(int futNum, void *m, int PE)
176 {
177   UsrToEnv(m)->setRef(futNum);
178   fBOC.SetFuture((FutureInitMsg *)m,PE);
179 }
180
181 #include "CkFutures.def.h"