doc: Add serial to list of ci file reserved words
[charm.git] / src / conv-core / futures.c
index 31916e00141895a9431a0437c1d38463f351a9dc..f81aa3c6f16c63d8f34d82e244495b675c40d2bb 100644 (file)
@@ -1,14 +1,26 @@
+#include <stdlib.h>
+#include <string.h>
 #include "converse.h"
 
 typedef struct Cfuture_data_s
 {
-  CfutureValue value;
-  int          ready;
-  CthThread    waiters;
+  void      *value;
+  int        ready;
+  CthThread  waiters;
 }
 *futdata;
 
-#define field_offset(type, field) ((int)(&(((type)0)->field)))
+typedef struct CfutureValue_s
+{
+  char core[CmiMsgHeaderSizeBytes];
+  struct Cfuture_data_s *data;
+  int valsize;
+  double rest[1];
+}
+*CfutureValue;
+
+#define field_offset(t, f) ((size_t)(((t)0)->f))
+#define void_to_value(v) ((CfutureValue)(((char*)v)-field_offset(CfutureValue,rest)))
 
 CpvDeclare(int, CfutureStoreIndex);
 
@@ -16,6 +28,7 @@ Cfuture CfutureCreate()
 {
   futdata data = (futdata)malloc(sizeof(struct Cfuture_data_s));
   Cfuture result;
+  _MEMCHECK(data);
   data->value = 0;
   data->ready = 0;
   data->waiters = 0;
@@ -24,37 +37,38 @@ Cfuture CfutureCreate()
   return result;
 }
 
-CfutureValue CfutureCreateValue(int bytes)
-{
-  int valsize = sizeof(struct CfutureValue_s) + bytes;
-  CfutureValue m = (CfutureValue)CmiAlloc(valsize);
-  CmiSetHandler(m, CpvAccess(CfutureStoreIndex));
-  m->valsize = valsize;
-  return m;
-}
-
 static void CfutureAwaken(futdata data, CfutureValue val)
 {
   CthThread t;
   data->value = val;
   data->ready = 1;
-  t = data->waiters;
-  while (t) {
+  for (t=data->waiters; t; t=CthGetNext(t))
     CthAwaken(t);
-    t = CthGetNext(t);
-  }
   data->waiters=0;
 }
 
 static void CfutureStore(CfutureValue m)
 {
-  CmiGrabBuffer(&m);
   CfutureAwaken(m->data, m);
 }
 
-void CfutureSet(Cfuture f, CfutureValue m)
+void *CfutureCreateBuffer(int bytes)
 {
-  futdata data;
+  int valsize = sizeof(struct CfutureValue_s) + bytes;
+  CfutureValue m = (CfutureValue)CmiAlloc(valsize);
+  CmiSetHandler(m, CpvAccess(CfutureStoreIndex));
+  m->valsize = valsize;
+  return (void*)(m->rest);
+}
+
+void CfutureDestroyBuffer(void *v)
+{
+  CmiFree(v);
+}
+
+void CfutureStoreBuffer(Cfuture f, void *value)
+{
+  CfutureValue m = void_to_value(value);
   if (f.pe == CmiMyPe()) {
     CfutureAwaken(f.data, m);
   } else {
@@ -63,7 +77,14 @@ void CfutureSet(Cfuture f, CfutureValue m)
   }
 }
 
-CfutureValue CfutureWait(Cfuture f, int freeflag)
+void CfutureSet(Cfuture f, void *value, int len)
+{
+  void *copy = CfutureCreateBuffer(len);
+  memcpy(copy, value, len);
+  CfutureStoreBuffer(f, copy);
+}
+
+void *CfutureWait(Cfuture f)
 {
   CthThread self; CfutureValue value; futdata data;
   if (f.pe != CmiMyPe()) {
@@ -78,8 +99,7 @@ CfutureValue CfutureWait(Cfuture f, int freeflag)
     CthSuspend();
   }
   value = data->value;
-  if (freeflag) free(data);
-  return value;
+  return (void*)(value->rest);
 }
 
 void CfutureDestroy(Cfuture f)
@@ -92,16 +112,12 @@ void CfutureDestroy(Cfuture f)
     CmiPrintf("error: CfutureDestroy: destroying an active future.\n");
     exit(1);
   }
-  free(f);
-}
-
-void CfutureDestroyValue(CfutureValue v)
-{
-  CmiFree(v);
+  if (f.data->value) CmiFree(f.data->value);
+  free(f.data);
 }
 
-void CfutureInit()
+void CfutureModuleInit()
 {
   CpvInitialize(int, CfutureStoreIndex);
-  CpvAccess(CfutureStoreIndex) = CmiRegisterHandler(CfutureStore);
+  CpvAccess(CfutureStoreIndex) = CmiRegisterHandler((CmiHandler)CfutureStore);
 }