*** empty log message ***
[charm.git] / src / conv-core / futures.c
1 #include "converse.h"
2
3 typedef struct Cfuture_data_s
4 {
5   CfutureValue value;
6   int          ready;
7   CthThread    waiters;
8 }
9 *futdata;
10
11 #define field_offset(type, field) ((int)(&(((type)0)->field)))
12
13 CpvDeclare(int, CfutureStoreIndex);
14
15 Cfuture CfutureCreate()
16 {
17   futdata data = (futdata)malloc(sizeof(struct Cfuture_data_s));
18   Cfuture result;
19   data->value = 0;
20   data->ready = 0;
21   data->waiters = 0;
22   result.pe = CmiMyPe();
23   result.data = data;
24   return result;
25 }
26
27 CfutureValue CfutureCreateValue(int bytes)
28 {
29   int valsize = sizeof(struct CfutureValue_s) + bytes;
30   CfutureValue m = (CfutureValue)CmiAlloc(valsize);
31   CmiSetHandler(m, CpvAccess(CfutureStoreIndex));
32   m->valsize = valsize;
33   return m;
34 }
35
36 static void CfutureAwaken(futdata data, CfutureValue val)
37 {
38   CthThread t;
39   data->value = val;
40   data->ready = 1;
41   t = data->waiters;
42   while (t) {
43     CthAwaken(t);
44     t = CthGetNext(t);
45   }
46   data->waiters=0;
47 }
48
49 static void CfutureStore(CfutureValue m)
50 {
51   CmiGrabBuffer(&m);
52   CfutureAwaken(m->data, m);
53 }
54
55 void CfutureSet(Cfuture f, CfutureValue m)
56 {
57   futdata data;
58   if (f.pe == CmiMyPe()) {
59     CfutureAwaken(f.data, m);
60   } else {
61     m->data = f.data;
62     CmiSyncSendAndFree(f.pe, m->valsize, m);
63   }
64 }
65
66 CfutureValue CfutureWait(Cfuture f, int freeflag)
67 {
68   CthThread self; CfutureValue value; futdata data;
69   if (f.pe != CmiMyPe()) {
70     CmiPrintf("error: CfutureWait: future not local.\n");
71     exit(1);
72   }
73   data = f.data;
74   if (data->ready == 0) {
75     self = CthSelf();
76     CthSetNext(self, data->waiters);
77     data->waiters = self;
78     CthSuspend();
79   }
80   value = data->value;
81   if (freeflag) free(data);
82   return value;
83 }
84
85 void CfutureDestroy(Cfuture f)
86 {
87   if (f.pe != CmiMyPe()) {
88     CmiPrintf("error: CfutureDestroy: future not local.\n");
89     exit(1);
90   }
91   if (f.data->waiters) {
92     CmiPrintf("error: CfutureDestroy: destroying an active future.\n");
93     exit(1);
94   }
95   free(f);
96 }
97
98 void CfutureDestroyValue(CfutureValue v)
99 {
100   CmiFree(v);
101 }
102
103 void CfutureInit()
104 {
105   CpvInitialize(int, CfutureStoreIndex);
106   CpvAccess(CfutureStoreIndex) = CmiRegisterHandler(CfutureStore);
107 }