*** empty log message ***
authorJosh Yelon <jyelon@uiuc.edu>
Thu, 24 Jul 1997 18:32:02 +0000 (18:32 +0000)
committerJosh Yelon <jyelon@uiuc.edu>
Thu, 24 Jul 1997 18:32:02 +0000 (18:32 +0000)
src/Makefile
src/conv-core/converse.h
src/conv-core/cpthreads.c
src/conv-core/cpthreads.h
src/conv-core/futures.c [new file with mode: 0644]
src/conv-core/threads.c
src/langs/simplemsg/simplemsg.c [new file with mode: 0644]
src/langs/simplemsg/simplemsg.h [new file with mode: 0644]
src/lib-misc/futureDoc.tex [deleted file]
src/lib-misc/futures.c [deleted file]

index 4665da7749e2278a98921726d9195eec0fb17d82..118960b17fa2ecf4dbce547aaac85186a4a1facd 100644 (file)
@@ -56,7 +56,7 @@ CHARMC=../bin/charmc $(CHARMOPTS) $(OPTS)
 #
 ###############################################################################
 
-ALLHEADERS=acc.h c++interface.h chare.h ckdefs.h common.h communication.h condsend.h const.h cpthreads.h dagger.h dtable.h env_macros.h globals.h mono.h msg_macros.h prio_macros.h qd.h stat.h sys_macros.h table.h tbl.h trans_decls.h trans_defs.h trans_externs.h user_macros.h vid.h wrtone.h converse.h conv-mach.h internal.h quiescence.h trace.h dag.h generic_redn.h charmFuturesInclude.h # pglib.h
+ALLHEADERS=acc.h c++interface.h chare.h ckdefs.h common.h communication.h condsend.h const.h cpthreads.h dagger.h dtable.h env_macros.h globals.h mono.h msg_macros.h prio_macros.h qd.h stat.h sys_macros.h table.h tbl.h trans_decls.h trans_defs.h trans_externs.h user_macros.h vid.h wrtone.h converse.h conv-mach.h internal.h quiescence.h simplemsg.h trace.h dag.h generic_redn.h charmFuturesInclude.h # pglib.h
 
 ALLINTERFACES=GENERIC-ACC.int GENERIC-HIST.int GENERIC-REDN.int barrier_redn.int cache.int dacc_count.int dacc_hist.int dcountredn.int dmaxredn.int dminredn.int dprodredn.int dsumredn.int facc_count.int facc_hist.int fcountredn.int fmaxredn.int fminredn.int fprodredn.int fsumredn.int iacc_count.int iacc_hist.int icountredn.int imaxredn.int iminredn.int iprodredn.int isumredn.int pg.int
 
@@ -133,7 +133,7 @@ CVHEADERS=converse.h conv-mach.h conv-mach.csh
 
 CVLIBS=libconv-core.a libconv-cplus-n.a libconv-cplus-y.a
 
-LIBCONV_CORE=threads.o convcore.o conv-conds.o spantree.o queueing.o fifo.o msgmgr.o memory.o cpm.o cpthreads.o
+LIBCONV_CORE=threads.o convcore.o conv-conds.o spantree.o queueing.o fifo.o msgmgr.o memory.o cpm.o cpthreads.o futures.o
 
 converse: basics QuickThreads/libqt.a $(CVLIBS) conv-host-if-needed conv-cpm
 
@@ -181,6 +181,9 @@ queueing.o: queueing.c $(CVHEADERS)
 conv-conds.o: conv-conds.c $(CVHEADERS)
        $(CHARMC) conv-conds.c
 
+futures.o: futures.c $(CVHEADERS)
+       $(CHARMC) futures.c
+
 msgmgr.o: msgmgr.c $(CVHEADERS)
        $(CHARMC) msgmgr.c
 
@@ -358,7 +361,7 @@ LIBCHARM=cache.o dag.o barrier_redn.o pglib.o \
          iminredn.o imaxredn.o isumredn.o iprodredn.o icountredn.o \
         fminredn.o fmaxredn.o fsumredn.o fprodredn.o \
         dminredn.o dmaxredn.o dsumredn.o dprodredn.o \
-        charmFutures.o futures.o
+        charmFutures.o
 
 libcharm: charmxlat libcharm.a
 
@@ -440,9 +443,6 @@ dprodredn.o: dprodredn.int $(GENERIC_REDN_H)
 dcountredn.o: dcountredn.int $(GENERIC_REDN_H)
        $(CHARMC) -o dcountredn.o GENERIC-REDN.p -DHEAD='"dcountredn.int"'
 
-futures.o: futures.c
-       $(CHARMC) -c futures.c
-
 charmFutures.o: charmFutures.C
        $(CHARMC) charmFutures.ci
        $(CHARMC) -c charmFutures.C
@@ -563,6 +563,15 @@ xi-parse.tab.o: xi-parse.tab.C $(XIHEADERS)
 xi-scan.o: xi-scan.C $(XIHEADERS)
        $(CHARMC) -seq xi-scan.C
 
+###############################################################################
+#
+# Little languages.
+#
+###############################################################################
+
+libsimplemsg.a: simplemsg.c simplemsg.h
+       $(CHARMC) -cp ../lib/ -o $@ simplemsg.c
+
 ###############################################################################
 #
 # Make clean
index ed1dd8e41fb59a0d94da04fc8250c98c05e3cb69..769ab2479ba8604034919f36d1163aa3fda40feb 100644 (file)
  * REVISION HISTORY:
  *
  * $Log$
- * Revision 2.66  1997-07-24 17:29:36  milind
+ * Revision 2.67  1997-07-24 18:32:12  jyelon
+ * *** empty log message ***
+ *
+ * Revision 2.66  1997/07/24 17:29:36  milind
  * Added Parallel Java to the CVS repository in Common/langs.
  * Fixed a problem with size_t in converse.h
  *
@@ -496,7 +499,9 @@ extern void CmiNumberHandler CMK_PROTO((int, CmiHandler));
  * If neither bit is set, the numbers are in local format, and no
  * conversion is needed whatsoever.  Thus, a value of 0 indicates that
  * the message is entirely in local format.  If the values are in wildly
- * different order, one has no choice but to use the CmiConvert functions.
+ * different format, one has no choice but to use the CmiConvert functions.
+ * If they're just in backward-byte-order, you can swap the bytes yourself,
+ * possibly faster than we can.
  *
  */
 
@@ -546,6 +551,8 @@ int   CmiScanf  CMK_PROTO((char *, ...));
 #define CmiScanf  scanf
 #endif
 
+typedef void (*CmiStartFn) CMK_PROTO((int argc, char **argv));
+
 /********* CSD - THE SCHEDULER ********/
 
 extern  int CsdScheduler CMK_PROTO((int));
@@ -633,67 +640,15 @@ void       CthAwaken              CMK_PROTO((CthThread));
 void       CthSetStrategy         CMK_PROTO((CthThread, CthVoidFn, CthThFn));
 void       CthSetStrategyDefault  CMK_PROTO((CthThread));
 void       CthYield               CMK_PROTO((void));
+
+void       CthSetNext CMK_PROTO((CthThread t, CthThread next));
+CthThread  CthGetNext CMK_PROTO((CthThread t));
+
 void       CthAutoYield           CMK_PROTO((CthThread t, int flag));
 double     CthAutoYieldFreq       CMK_PROTO((CthThread t));
 void       CthAutoYieldBlock      CMK_PROTO((void));
 void       CthAutoYieldUnblock    CMK_PROTO((void));
 
-/****** CPTHREAD: the posix threads package ******/
-
-#include <sys/types.h>
-
-#define CPTHREAD_ONCE_INIT 0
-
-typedef int                         Cpthread_once_t;
-typedef struct Cpthread_attr_s      Cpthread_attr_t;
-typedef struct Cpthread_key_s      *Cpthread_key_t;
-typedef struct Cpthread_cleanup_s  *Cpthread_cleanup_t;
-typedef struct Cpthread_mutexattr_s Cpthread_mutexattr_t;
-typedef struct Cpthread_condattr_s  Cpthread_condattr_t;
-typedef struct Cpthread_mutex_s     Cpthread_mutex_t;
-typedef struct Cpthread_cond_s      Cpthread_cond_t;
-typedef struct Cpthread_s          *Cpthread_t;
-
-Cpthread_t Cpthread_self();
-int   Cpthread_attr_init(Cpthread_attr_t *attr);
-int   Cpthread_attr_destroy(Cpthread_attr_t *attr);
-int   Cpthread_attr_getstacksize(Cpthread_attr_t *attr, size_t *size);
-int   Cpthread_attr_setstacksize(Cpthread_attr_t *attr, size_t size);
-int   Cpthread_attr_getdetachstate(Cpthread_attr_t *attr, int *state);
-int   Cpthread_attr_setdetachstate(Cpthread_attr_t *attr, int state);
-int   Cpthread_key_create(Cpthread_key_t *keyp, void (*destructo)(void *));
-int   Cpthread_key_delete(Cpthread_key_t key);
-int   Cpthread_setspecific(Cpthread_key_t key, void *val);
-void *Cpthread_getspecific(Cpthread_key_t key);
-void  Cpthread_cleanup_push(void (*routine)(void*), void *arg);
-void  Cpthread_cleanup_pop(int execute);
-void  Cpthread_exit(void *status);
-void  Cpthread_top(Cpthread_t pt);
-int   Cpthread_create(Cpthread_t *thread, Cpthread_attr_t *attr,
-                     void *(*fn)(void *), void *arg);
-int   Cpthread_equal(Cpthread_t t1, Cpthread_t t2);
-int   Cpthread_detach(Cpthread_t pt);
-int   Cpthread_join(Cpthread_t pt, void **status);
-int   Cpthread_mutexattr_init(Cpthread_mutexattr_t *mattr);
-int   Cpthread_mutexattr_destroy(Cpthread_mutexattr_t *mattr);
-int   Cpthread_mutexattr_getpshared(Cpthread_mutexattr_t *mattr,int *pshared);
-int   Cpthread_mutexattr_setpshared(Cpthread_mutexattr_t *mattr,int  pshared);
-int   Cpthread_mutex_init(Cpthread_mutex_t *mutex,Cpthread_mutexattr_t *mattr);
-int   Cpthread_mutex_destroy(Cpthread_mutex_t *mutex);
-int   Cpthread_mutex_lock(Cpthread_mutex_t *mutex);
-int   Cpthread_mutex_trylock(Cpthread_mutex_t *mutex);
-int   Cpthread_mutex_unlock(Cpthread_mutex_t *mutex);
-int   Cpthread_condattr_init(Cpthread_condattr_t *cattr);
-int   Cpthread_condattr_destroy(Cpthread_condattr_t *cattr);
-int   Cpthread_condattr_getpshared(Cpthread_condattr_t *cattr, int *pshared);
-int   Cpthread_condattr_setpshared(Cpthread_condattr_t *cattr, int pshared);
-int   Cpthread_cond_init(Cpthread_cond_t *cond, Cpthread_condattr_t *cattr);
-int   Cpthread_cond_destroy(Cpthread_cond_t *cond);
-int   Cpthread_cond_wait(Cpthread_cond_t *cond, Cpthread_mutex_t *mutex);
-int   Cpthread_cond_signal(Cpthread_cond_t *cond);
-int   Cpthread_cond_broadcast(Cpthread_cond_t *cond);
-int   Cpthread_once(Cpthread_once_t *once, void (*fn)(void));
-
 /****** CTH: THREAD-PRIVATE VARIABLES ******/
 
 #if CMK_THREADS_REQUIRE_NO_CPV
@@ -717,8 +672,8 @@ int   Cpthread_once(Cpthread_once_t *once, void (*fn)(void));
 CthCpvExtern(char *,CthData);
 extern int CthRegister CMK_PROTO((int));
 #define CtvDeclare(t,v)         typedef t CtvType##v; CsvDeclare(int,CtvOffs##v);
-#define CtvStaticDeclare(t,v)   typedef t CtvType##v; CsvDeclare(int,CtvOffs##v);
-#define CtvExtern(t,v)          typedef t CtvType##v; CsvDeclare(int,CtvOffs##v);
+#define CtvStaticDeclare(t,v)   typedef t CtvType##v; CsvStaticDeclare(int,CtvOffs##v);
+#define CtvExtern(t,v)          typedef t CtvType##v; CsvExtern(int,CtvOffs##v);
 #define CtvAccess(v)            (*((CtvType##v *)(CthCpvAccess(CthData)+CsvAccess(CtvOffs##v))))
 #define CtvInitialize(t,v)      if (CmiMyRank()==0) (CsvAccess(CtvOffs##v)=CthRegister(sizeof(CtvType##v)));
 
@@ -826,6 +781,10 @@ CpmDeclareSimple(CpmDim);
 #define CpmPack_CpmDim(v)
 #define CpmUnpack_CpmDim(v)
 
+CpmDeclareSimple(Cfuture);
+#define CpmPack_Cfuture(v)
+#define CpmUnpack_Cfuture(v)
+
 typedef char *CpmStr;
 CpmDeclarePointer(CpmStr);
 #define CpmPtrSize_CpmStr(v) (strlen(v)+1)
@@ -833,6 +792,36 @@ CpmDeclarePointer(CpmStr);
 #define CpmPtrUnpack_CpmStr(v)
 #define CpmPtrFree_CpmStr(v)
 
+/****** CFUTURE: CONVERSE FUTURES ******/
+
+typedef struct Cfuture_s
+{
+  int pe;
+  struct Cfuture_data_s *data;
+}
+Cfuture;
+
+typedef struct CfutureValue_s
+{
+  char core[CmiMsgHeaderSizeBytes];
+  struct Cfuture_data_s *data;
+  int valsize;
+  double rest[1];
+}
+*CfutureValue;
+
+#define CfutureValueData(v) ((void*)((v)->rest))
+
+Cfuture       CfutureCreate(void);
+void          CfutureDestroy(Cfuture f);
+CfutureValue  CfutureCreateValue(int bytes);
+void          CfutureDestroyValue(CfutureValue v);
+void          CfutureSet(Cfuture f, CfutureValue val);
+CfutureValue  CfutureWait(Cfuture f, int freeflag);
+#define       CfuturePE(f) ((f).pe)
+
+void CfutureInit();
+
 /****** CMM: THE MESSAGE MANAGER ******/
 
 typedef struct CmmTableStruct *CmmTable;
@@ -848,8 +837,6 @@ void      *CmmFind CMK_PROTO((CmmTable t, int ntags, int *tags, int *returntags,
 
 /******** ConverseInit and ConverseExit ********/
 
-typedef void (*CmiStartFn) CMK_PROTO((int argc, char **argv));
-
 void ConverseInit CMK_PROTO((int, char**, CmiStartFn, int, int));
 void ConverseExit CMK_PROTO((void));
 
index 85a618088c1b854f26b500dd7e2a5a5c36c149dc..1aef97b08e8439a5c644f9930753a6ae781a0cd1 100644 (file)
@@ -1,6 +1,11 @@
 /*
  * TO-DO:
  *
+ * what about shared memory machines?
+ *
+ * what about the fact that posix threads programs exit when all
+ * threads have completed?
+ *
  * write errcode, errspan.  Figure out errno thing.
  *
  * there's obviously something I don't understand about cond... what's
  *
  */
 
-#include "converse.h"
+#define CPTHREAD_IS_HERE
+#include "cpthreads.h"
 #include <sys/errno.h>
 
-static void errcode(int number)
-{
-  CmiPrintf("Cpthreads: %s\n", strerror(number));
-  exit(1);
-}
-
-static void errspan()
-{
-  CmiPrintf("Error: Cpthreads sync primitives do not work across processor boundaries.\n");
-  exit(1);
-}
-
-
 /******************************************************************************
  *
  * Magic Numbers
@@ -54,11 +47,15 @@ static void errspan()
  *
  *****************************************************************************/
  
+typedef void *(*voidfn)();
+
 struct Cpthread_s
 {
   int magic;
-  void *(*startfn)(void *);
-  void *startarg;
+  voidfn startfn;
+  void *startarg1;
+  void *startarg2;
+  void *startarg3;
   int detached;
   void *joinstatus;
   Cpthread_cleanup_t cleanups;
@@ -66,7 +63,7 @@ struct Cpthread_s
   CthThread thread;
 };
 
-CtvStaticDeclare(Cpthread_t, this_pthread);
+#define errcode(n) { Cpthread_errno=(n); return -1; }
 
 
 /******************************************************************************
@@ -92,34 +89,33 @@ struct Cpthread_key_s
   Cpthread_key_t next;
 };
 
-CpvStaticDeclare(Cpthread_key_t, keys_active);
-CpvStaticDeclare(Cpthread_key_t, keys_inactive);
+Cpthread_key_t keys_active = 0;
+Cpthread_key_t keys_inactive = 0;
 
 int Cpthread_key_create(Cpthread_key_t *keyp, void (*destructo)(void *))
 {
   Cpthread_key_t key;
-  key = CpvAccess(keys_inactive);
+  key = keys_inactive;
   if (key) {
-    CpvAccess(keys_inactive) = key->next;
+    keys_inactive = key->next;
   } else {
     key = (Cpthread_key_t)malloc(sizeof(struct Cpthread_key_s));
     key->offset = CthRegister(sizeof(void *));
   }
   key->magic = KEY_MAGIC;
   key->destructo = destructo;
-  key->next = CpvAccess(keys_active);
-  CpvAccess(keys_active) = key;
+  key->next = keys_active;
+  keys_active = key;
   *keyp = key;
   return 0;
 }
 
 int Cpthread_key_delete(Cpthread_key_t key)
 {
-  Cpthread_key_t active;
-  active = CpvAccess(keys_active);
+  Cpthread_key_t active = keys_active;
   if (key->magic != KEY_MAGIC) errcode(EINVAL);
   if (active==key) {
-    CpvAccess(keys_active) = key->next;
+    keys_active = key->next;
   } else {
     while (active) {
       if (active->next == key) {
@@ -132,8 +128,8 @@ int Cpthread_key_delete(Cpthread_key_t key)
   }
 deleted:
   key->magic = FKEY_MAGIC;
-  key->next = CpvAccess(keys_inactive);
-  CpvAccess(keys_inactive) = key;
+  key->next = keys_inactive;
+  keys_inactive = key;
 }
 
 int Cpthread_setspecific(Cpthread_key_t key, void *val)
@@ -147,9 +143,8 @@ int Cpthread_setspecific(Cpthread_key_t key, void *val)
 
 void *Cpthread_getspecific(Cpthread_key_t key)
 {
-  char *data;
-  data = CthCpvAccess(CthData);
-  if (key->magic != KEY_MAGIC) errcode(EINVAL);
+  char *data = CthCpvAccess(CthData);
+  if (key->magic != KEY_MAGIC) return 0;
   return *((void **)(data+(key->offset)));
 }
 
@@ -171,7 +166,7 @@ struct Cpthread_cleanup_s
 
 void Cpthread_cleanup_push(void (*routine)(void*), void *arg)
 {
-  Cpthread_t pt = CtvAccess(this_pthread);
+  Cpthread_t pt = CtvAccess(Cpthread_current);
   Cpthread_cleanup_t c =
     (Cpthread_cleanup_t)malloc(sizeof(struct Cpthread_cleanup_s));
   c->routine = routine;
@@ -182,7 +177,7 @@ void Cpthread_cleanup_push(void (*routine)(void*), void *arg)
 
 void Cpthread_cleanup_pop(int execute)
 {
-  Cpthread_t pt = CtvAccess(this_pthread);
+  Cpthread_t pt = CtvAccess(Cpthread_current);
   Cpthread_cleanup_t c = pt->cleanups;
   if (c) {
     pt->cleanups = c->next;
@@ -205,13 +200,6 @@ void Cpthread_cleanup_pop(int execute)
  *
  *****************************************************************************/
 
-struct Cpthread_attr_s
-{
-  int magic;
-  int detached;
-  int stacksize;
-};
-
 int Cpthread_attr_init(Cpthread_attr_t *attr)
 {
   attr->magic = ATTR_MAGIC;
@@ -261,46 +249,58 @@ int Cpthread_attr_setdetachstate(Cpthread_attr_t *attr, int state)
  *
  * Every thread is associated with a CthThread and a pthread_t (which are
  * separate from each other).  The pthread_t contains a field pointing to the
- * CthThread, and the CthThread has a thread-private variable ``this_pthread''
+ * CthThread, and the CthThread has a thread-private variable ``Cpthread_current''
  * pointing to the pthread_t.
  *
  *****************************************************************************/
 
 void Cpthread_top(Cpthread_t pt)
 {
-  void *(*fn)(void *); void *arg, *result; 
-  Cpthread_key_t k; char *data;
+  Cpthread_key_t k; char *data; void *result; 
 
   data = CthCpvAccess(CthData);
-  for (k=CpvAccess(keys_active); k; k=k->next)
+  for (k=keys_active; k; k=k->next)
     *(void **)(data+(k->offset)) = 0;
-  result = (pt->startfn)(pt->startarg);
+  CtvAccess(Cpthread_errcode) = 0;
+  CtvAccess(Cpthread_current) = pt;
+  result = (pt->startfn)(pt->startarg1, pt->startarg2, pt->startarg3);
   Cpthread_exit(result);
 }
 
-int Cpthread_create(Cpthread_t *thread, Cpthread_attr_t *attr,
-                  void *(*fn)(void *), void *arg)
+int Cpthread_create3(Cpthread_t *thread, Cpthread_attr_t *attr,
+                    voidfn fn, void *a1, void *a2, void *a3)
 {
   Cpthread_t pt;
   if (attr->magic != ATTR_MAGIC) errcode(EINVAL);
   pt = (Cpthread_t)malloc(sizeof(struct Cpthread_s));
+  pt->magic = PT_MAGIC;
   pt->startfn = fn;
-  pt->startarg = arg;
+  pt->startarg1 = a1;
+  pt->startarg2 = a2;
+  pt->startarg3 = a3;
   pt->detached = attr->detached;
   pt->joinstatus = 0;
   pt->cleanups = 0;
   pt->waiting = 0;
   pt->thread = CthCreate((CthVoidFn)Cpthread_top, (void *)pt, attr->stacksize);
+  CthSetStrategyDefault(pt->thread);
+  CthAwaken(pt->thread);
   *thread = pt;
   return 0;
 }
 
+int Cpthread_create(Cpthread_t *thread, Cpthread_attr_t *attr,
+                    voidfn fn, void *arg)
+{
+  Cpthread_create3(thread, attr, fn, arg, 0, 0);
+}
+
 void Cpthread_exit(void *status)
 {
   Cpthread_t pt; Cpthread_cleanup_t c, cn; Cpthread_key_t k;
   void *priv; char *data; CthThread t;
 
-  pt = CtvAccess(this_pthread);
+  pt = CtvAccess(Cpthread_current);
   t = pt->thread;
   c = pt->cleanups;
   data = CthCpvAccess(CthData);
@@ -312,7 +312,7 @@ void Cpthread_exit(void *status)
     free(c); c=cn;
   }
   /* execute destructors for thread-private data */
-  k = CpvAccess(keys_active);
+  k = keys_active;
   while (k) {
     if (k->destructo) {
       priv = *(void **)(data+(k->offset));
@@ -323,12 +323,12 @@ void Cpthread_exit(void *status)
   /* handle the join-operation */
   if (pt->detached) {
     free(pt);
+    pt->magic = 0;
   } else {
     pt->joinstatus = status;
     pt->thread = 0;
     if (pt->waiting) CthAwaken(pt->waiting);
   }
-  pt->magic = 0;
   CthFree(t);
   CthSuspend();
 }
@@ -338,15 +338,11 @@ int Cpthread_equal(Cpthread_t t1, Cpthread_t t2)
   return (t1==t2);
 }
 
-Cpthread_t Cpthread_self()
-{
-  return CtvAccess(this_pthread);
-}
-
 int Cpthread_detach(Cpthread_t pt)
 {
   if (pt->magic != PT_MAGIC) errcode(EINVAL);
   if (pt->thread==0) {
+    pt->magic = 0;
     free(pt);
   } else {
     pt->detached = 1;
@@ -368,8 +364,13 @@ int Cpthread_join(Cpthread_t pt, void **status)
 
 int Cpthread_once(Cpthread_once_t *once, void (*fn)(void))
 {
-  if (*once) return 0;
-  *once = 1;
+  int rank = CmiMyRank();
+  if (rank>=32) {
+    CmiPrintf("error: cpthreads current implementation limited to 32 PE's per node.\n");
+    exit(1);
+  }
+  if (once->flag[rank]) return 0;
+  once->flag[rank] = 1;
   fn();
 }
 
@@ -382,18 +383,11 @@ int Cpthread_once(Cpthread_once_t *once, void (*fn)(void))
  *
  *****************************************************************************/
 
-struct Cpthread_mutexattr_s
-{
-  int magic;
-  int pshared;
-};
-
-struct Cpthread_mutex_s
+static void errspan()
 {
-  int magic;
-  int onpe;
-  void *users; /* fifo queue --- first on queue owns lock */
-};
+  CmiPrintf("Error: Cpthreads sync primitives do not work across processor boundaries.\n");
+  exit(1);
+}
 
 int Cpthread_mutexattr_init(Cpthread_mutexattr_t *mattr)
 {
@@ -483,19 +477,6 @@ int Cpthread_mutex_unlock(Cpthread_mutex_t *mutex)
  *
  *****************************************************************************/
 
-struct Cpthread_condattr_s
-{
-  int magic;
-  int pshared;
-};
-
-struct Cpthread_cond_s
-{
-  int magic;
-  int onpe;
-  void *users; /* fifo queue --- threads waiting on condition */
-};
-
 int Cpthread_condattr_init(Cpthread_condattr_t *cattr)
 {
   cattr->magic = CATTR_MAGIC;
@@ -586,3 +567,32 @@ int Cpthread_cond_broadcast(Cpthread_cond_t *cond)
   return 0;
 }
 
+/******************************************************************************
+ *
+ * Module initialization
+ *
+ *****************************************************************************/
+
+typedef void (*mainfn)(int argc, char **argv);
+
+int Cpthread_init()
+{
+  return 0;
+}
+
+void Cpthread_initialize()
+{
+  CtvInitialize(Cpthread_t, Cpthread_current);
+  CtvInitialize(int,        Cpthread_errcode);
+}
+
+void Cpthread_start_main(mainfn fn, int argc, char **argv)
+{
+  Cpthread_t pt;
+  Cpthread_attr_t attrib;
+  if (CmiMyRank()==0) {
+    Cpthread_attr_init(&attrib);
+    Cpthread_attr_setdetachstate(&attrib, 1);
+    Cpthread_create3(&pt, &attrib, (voidfn)fn, (void *)argc, argv, 0);
+  }
+}
index cd34e40b55cdb5e858df9680492fe43aad07b12d..22c112337e8c738b72a8b43392c5ea6ff73fd63d 100644 (file)
@@ -2,6 +2,126 @@
 #ifndef CPTHREADS_H
 #define CPTHREADS_H
 
+#include <converse.h>
+
+#define CPTHREAD_THREADS_MAX     1000000000
+#define CPTHREAD_KEYS_MAX        1000000000
+#define CPTHREAD_STACK_MIN       32768
+#define CPTHREAD_CREATE_DETACHED 1
+#define CPTHREAD_CREATE_JOINABLE 0
+
+struct Cpthread_attr_s
+{
+  int magic;
+  int detached;
+  int stacksize;
+};
+
+struct Cpthread_mutexattr_s
+{
+  int magic;
+  int pshared;
+};
+
+struct Cpthread_mutex_s
+{
+  int magic;
+  int onpe;
+  void *users;
+};
+
+struct Cpthread_condattr_s
+{
+  int magic;
+  int pshared;
+};
+
+struct Cpthread_cond_s
+{
+  int magic;
+  int onpe;
+  void *users;
+};
+
+typedef struct { int flag[32]; } Cpthread_once_t;
+
+#define CPTHREAD_ONCE_INIT {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+
+typedef struct Cpthread_attr_s      Cpthread_attr_t;
+typedef struct Cpthread_key_s      *Cpthread_key_t;
+typedef struct Cpthread_cleanup_s  *Cpthread_cleanup_t;
+typedef struct Cpthread_mutexattr_s Cpthread_mutexattr_t;
+typedef struct Cpthread_condattr_s  Cpthread_condattr_t;
+typedef struct Cpthread_mutex_s     Cpthread_mutex_t;
+typedef struct Cpthread_cond_s      Cpthread_cond_t;
+typedef struct Cpthread_s          *Cpthread_t;
+
+#ifdef CPTHREAD_IS_HERE
+CtvDeclare(Cpthread_t,  Cpthread_current);
+CtvDeclare(int,         Cpthread_errcode);
+#else
+CtvExtern(Cpthread_t,  Cpthread_current);
+CtvExtern(int,         Cpthread_errcode);
+#endif
+
+#define Cpthread_self() (CtvAccess(Cpthread_current))
+#define Cpthread_errno (CtvAccess(Cpthread_errcode))
+
+int   Cpthread_attr_init(Cpthread_attr_t *attr);
+int   Cpthread_attr_destroy(Cpthread_attr_t *attr);
+int   Cpthread_attr_getstacksize(Cpthread_attr_t *attr, size_t *size);
+int   Cpthread_attr_setstacksize(Cpthread_attr_t *attr, size_t size);
+int   Cpthread_attr_getdetachstate(Cpthread_attr_t *attr, int *state);
+int   Cpthread_attr_setdetachstate(Cpthread_attr_t *attr, int state);
+int   Cpthread_key_create(Cpthread_key_t *keyp, void (*destructo)(void *));
+int   Cpthread_key_delete(Cpthread_key_t key);
+int   Cpthread_setspecific(Cpthread_key_t key, void *val);
+void *Cpthread_getspecific(Cpthread_key_t key);
+void  Cpthread_cleanup_push(void (*routine)(void*), void *arg);
+void  Cpthread_cleanup_pop(int execute);
+void  Cpthread_exit(void *status);
+void  Cpthread_top(Cpthread_t pt);
+int   Cpthread_create(Cpthread_t *thread, Cpthread_attr_t *attr,
+                     void *(*fn)(void *), void *arg);
+int   Cpthread_equal(Cpthread_t t1, Cpthread_t t2);
+int   Cpthread_detach(Cpthread_t pt);
+int   Cpthread_join(Cpthread_t pt, void **status);
+int   Cpthread_mutexattr_init(Cpthread_mutexattr_t *mattr);
+int   Cpthread_mutexattr_destroy(Cpthread_mutexattr_t *mattr);
+int   Cpthread_mutexattr_getpshared(Cpthread_mutexattr_t *mattr,int *pshared);
+int   Cpthread_mutexattr_setpshared(Cpthread_mutexattr_t *mattr,int  pshared);
+int   Cpthread_mutex_init(Cpthread_mutex_t *mutex,Cpthread_mutexattr_t *mattr);
+int   Cpthread_mutex_destroy(Cpthread_mutex_t *mutex);
+int   Cpthread_mutex_lock(Cpthread_mutex_t *mutex);
+int   Cpthread_mutex_trylock(Cpthread_mutex_t *mutex);
+int   Cpthread_mutex_unlock(Cpthread_mutex_t *mutex);
+int   Cpthread_condattr_init(Cpthread_condattr_t *cattr);
+int   Cpthread_condattr_destroy(Cpthread_condattr_t *cattr);
+int   Cpthread_condattr_getpshared(Cpthread_condattr_t *cattr, int *pshared);
+int   Cpthread_condattr_setpshared(Cpthread_condattr_t *cattr, int pshared);
+int   Cpthread_cond_init(Cpthread_cond_t *cond, Cpthread_condattr_t *cattr);
+int   Cpthread_cond_destroy(Cpthread_cond_t *cond);
+int   Cpthread_cond_wait(Cpthread_cond_t *cond, Cpthread_mutex_t *mutex);
+int   Cpthread_cond_signal(Cpthread_cond_t *cond);
+int   Cpthread_cond_broadcast(Cpthread_cond_t *cond);
+int   Cpthread_once(Cpthread_once_t *once, void (*fn)(void));
+
+int Cpthread_init();
+
+void Cpthread_initialize();
+void Cpthread_start_main(CmiStartFn fn, int argc, char **argv);
+
+
+#ifdef CPTHREAD_DEFINE_PTHREADS
+
+#define PTHREAD_THREADS_MAX            CPTHREAD_THREADS_MAX
+#define PTHREAD_KEYS_MAX               CPTHREAD_KEYS_MAX
+#define PTHREAD_STACK_MIN              CPTHREAD_STACK_MIN
+#define PTHREAD_CREATE_DETACHED                CPTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_JOINABLE                CPTHREAD_CREATE_JOINABLE
+
+#define PTHREAD_ONCE_INIT               CPTHREAD_ONCE_INIT
+
 #define pthread_once_t                  Cpthread_once_t
 #define pthread_attr_t                  Cpthread_attr_t
 #define pthread_key_t                   Cpthread_key_t
 #define pthread_cond_signal             Cpthread_cond_signal
 #define pthread_cond_broadcast          Cpthread_cond_broadcast
 #define pthread_once                    Cpthread_once
+#define pthread_init                    Cpthread_init
+
+#endif /* CPTHREAD_DEFINE_PTHREADS */
 
 #endif /* CPTHREAD_H */
 
diff --git a/src/conv-core/futures.c b/src/conv-core/futures.c
new file mode 100644 (file)
index 0000000..31916e0
--- /dev/null
@@ -0,0 +1,107 @@
+#include "converse.h"
+
+typedef struct Cfuture_data_s
+{
+  CfutureValue value;
+  int          ready;
+  CthThread    waiters;
+}
+*futdata;
+
+#define field_offset(type, field) ((int)(&(((type)0)->field)))
+
+CpvDeclare(int, CfutureStoreIndex);
+
+Cfuture CfutureCreate()
+{
+  futdata data = (futdata)malloc(sizeof(struct Cfuture_data_s));
+  Cfuture result;
+  data->value = 0;
+  data->ready = 0;
+  data->waiters = 0;
+  result.pe = CmiMyPe();
+  result.data = data;
+  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) {
+    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)
+{
+  futdata data;
+  if (f.pe == CmiMyPe()) {
+    CfutureAwaken(f.data, m);
+  } else {
+    m->data = f.data;
+    CmiSyncSendAndFree(f.pe, m->valsize, m);
+  }
+}
+
+CfutureValue CfutureWait(Cfuture f, int freeflag)
+{
+  CthThread self; CfutureValue value; futdata data;
+  if (f.pe != CmiMyPe()) {
+    CmiPrintf("error: CfutureWait: future not local.\n");
+    exit(1);
+  }
+  data = f.data;
+  if (data->ready == 0) {
+    self = CthSelf();
+    CthSetNext(self, data->waiters);
+    data->waiters = self;
+    CthSuspend();
+  }
+  value = data->value;
+  if (freeflag) free(data);
+  return value;
+}
+
+void CfutureDestroy(Cfuture f)
+{
+  if (f.pe != CmiMyPe()) {
+    CmiPrintf("error: CfutureDestroy: future not local.\n");
+    exit(1);
+  }
+  if (f.data->waiters) {
+    CmiPrintf("error: CfutureDestroy: destroying an active future.\n");
+    exit(1);
+  }
+  free(f);
+}
+
+void CfutureDestroyValue(CfutureValue v)
+{
+  CmiFree(v);
+}
+
+void CfutureInit()
+{
+  CpvInitialize(int, CfutureStoreIndex);
+  CpvAccess(CfutureStoreIndex) = CmiRegisterHandler(CfutureStore);
+}
index d45b3439eb84630ed4e6944e7d6b0ef9c125389b..28cd3deaa5f6a5ad93b4a8bfde3460cf5fee5574 100644 (file)
@@ -126,6 +126,7 @@ struct CthThreadStruct
   int        autoyield_blocks;
   char      *data;
   int        datasize;
+  CthThread  qnext;
   qt_t      *stackp;
 };
 
@@ -150,6 +151,7 @@ CthThread t;
   t->choosefn = 0;
   t->data=0;
   t->datasize=0;
+  t->qnext=0;
   t->autoyield_enable = 0;
   t->autoyield_blocks = 0;
 }
@@ -323,4 +325,12 @@ void CthAutoYieldUnblock()
   CthCpvAccess(CthCurrent)->autoyield_blocks --;
 }
 
+void CthSetNext(CthThread t, CthThread v)
+{
+  t->qnext = v;
+}
 
+CthThread CthGetNext(CthThread t) 
+{
+  return t->qnext;
+}
diff --git a/src/langs/simplemsg/simplemsg.c b/src/langs/simplemsg/simplemsg.c
new file mode 100644 (file)
index 0000000..439b2c0
--- /dev/null
@@ -0,0 +1,98 @@
+#include <converse.h>
+#include "simplemsg.h"
+
+typedef struct CsmMessageStruct *CsmMessage;
+
+struct CsmMessageStruct
+{
+  char cmiheader[CmiMsgHeaderSizeBytes];
+  int seqno, size, ntags;
+  int tags[1];
+};
+
+CpvStaticDeclare(int, CsmHandlerIndex);
+CpvStaticDeclare(int *, CsmSeqOut);
+CpvStaticDeclare(int *, CsmSeqIn);
+CpvStaticDeclare(CmmTable, CsmMessages);
+CpvStaticDeclare(CmmTable, CsmSleepers);
+
+void CsmHandler(m)
+CsmMessage m;
+{
+  CthThread t;
+  CmiGrabBuffer(&m);
+  CmmPut(CpvAccess(CsmMessages), m->ntags, m->tags, m);
+  t = (CthThread)CmmGet(CpvAccess(CsmSleepers), m->ntags, m->tags, (int *)0);
+  if (t) CthAwaken(t);
+}
+
+void CsmInit(argv)
+char **argv;
+{
+  int *seqout, *seqin; int i;
+
+  seqout = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
+  seqin  = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
+  for (i=0; i<CmiNumPes(); i++) seqout[i] = 0;
+  for (i=0; i<CmiNumPes(); i++) seqin [i] = 0;
+
+  CpvInitialize(int, CsmHandlerIndex);
+  CpvInitialize(int *, CsmSeqOut);
+  CpvInitialize(int *, CsmSeqIn);
+  CpvInitialize(CmmTable, CsmMessages);
+  CpvInitialize(CmmTable, CsmSleepers);
+
+  CpvAccess(CsmHandlerIndex) = CmiRegisterHandler(CsmHandler);
+  CpvAccess(CsmSeqOut) = seqout;
+  CpvAccess(CsmSeqIn)  = seqin;
+  CpvAccess(CsmMessages) = CmmNew();
+  CpvAccess(CsmSleepers) = CmmNew();
+}
+
+void CsmTVSend(pe, ntags, tags, buffer, buflen)
+int pe, ntags;
+int *tags;
+void *buffer;
+int buflen;
+{
+  int headsize, totsize, i; CsmMessage msg;
+
+  headsize = sizeof(struct CsmMessageStruct) + (ntags*sizeof(int));
+  headsize = ((headsize + 7) & (~7));
+  totsize = headsize + buflen;
+  msg = (CsmMessage)CmiAlloc(totsize);
+  CmiSetHandler(msg, CpvAccess(CsmHandlerIndex));
+  msg->seqno = (CpvAccess(CsmSeqOut)[pe])++;
+  msg->size = buflen;
+  msg->ntags = ntags;
+  for (i=0; i<ntags; i++) msg->tags[i] = tags[i];
+  memcpy((((char *)msg)+headsize), buffer, buflen);
+  CmiSyncSend(pe, totsize, msg);
+}
+
+void CsmTVRecv(ntags, tags, buffer, buflen, rtags)
+int ntags;
+int *tags;
+void *buffer;
+int buflen;
+int *rtags;
+{
+  CsmMessage msg; CthThread self;
+  int headsize;
+
+  while (1) {  
+    msg = (CsmMessage)CmmGet(CpvAccess(CsmMessages), ntags, tags, rtags);
+    if (msg) break;
+    self = CthSelf();
+    CmmPut(CpvAccess(CsmSleepers), ntags, tags, self);
+    CthSuspend();
+  }
+  
+  if (msg->size > buflen) buflen = msg->size;
+  headsize = sizeof(struct CsmMessageStruct) + ((ntags-1)*sizeof(int));
+  headsize = ((headsize + 7) & (~7));
+  memcpy(buffer, ((char *)msg)+headsize, buflen);
+  CmiFree(msg);
+  return;
+}
+
diff --git a/src/langs/simplemsg/simplemsg.h b/src/langs/simplemsg/simplemsg.h
new file mode 100644 (file)
index 0000000..045b1ec
--- /dev/null
@@ -0,0 +1,14 @@
+
+#define CsmWildCard CmmWildCard
+
+void CsmTVSend
+  CMK_PROTO((int pe, int ntags, int *tags, void *buf, int buflen));
+
+void CsmTVRecv
+  CMK_PROTO((int ntags, int *tags, void *buf, int buflen, int *rtags));
+
+#define CsmTSend(pe, tag, buf, buflen)\
+  { int CsmTag=(tag); CsmTVSend(pe, 1, &CsmTag, buf, buflen); }
+
+#define CsmTRecv(tag, buf, buflen, rtag)\
+  { int CsmTag=(tag); CsmTVRecv(1, &CsmTag, buf, buflen, rtag); }
diff --git a/src/lib-misc/futureDoc.tex b/src/lib-misc/futureDoc.tex
deleted file mode 100644 (file)
index a7e6430..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-\documentstyle[psfig,11pt,epsf]{report}
-\setcounter{topnumber}{2}
-\def\topfraction{1}
-\setcounter{bottomnumber}{1}
-\def\bottomfraction{1}
-\setcounter{totalnumber}{3}
-\def\textfraction{0.2}
-\def\floatpagefraction{0.8}
-\setlength{\parindent}{0.0in}
-\setlength{\parskip}{0.1in}
-\setlength{\textwidth}{6.5in}
-\setlength{\itemindent}{1in}
-\setlength{\textheight}{9.5in}
-\addtolength{\oddsidemargin}{0in}
-\addtolength{\topmargin}{-0.4in}
-\textwidth 6.4in
-\textheight 8.9in
-\topmargin -.4in
-\oddsidemargin 0.25in
-\evensidemargin 0.25in
-\parskip 0.1in
-
-
-\begin{document}
-
-\begin{center}
-
-{\Large \bf Futures library}
-\end{center}
-This library supports the {\em future} abstraction, defined and used by
-Halstead and other researchers. The library itself provides only
-local (sequential) functions. If necessary, the user (or a language
-implementor who wishes to use futures) can send converse messages
-across processors, and have their handlers set the future's values.
-
-{\large \bf futuresInitialize}
-
-\verb#futuresInitialize()#
-
-This function initializes the futures module. It can deal with
-repeated (redundant) initializations, without losing information
-entered after the previous initialization. Currently, 100 distinct
-future values may be alive at any moment on each processor. This
-number will be made a parameter to the futuresInitialize function in
-future versions.
-
-{\large \bf createFuture}
-
-\verb#int createFuture()#
-
-Returns an integer key designating the future-value-holder just
-created.
-
-
-{\large \bf setFuture}
-
-\verb#setFuture(int key, void*pointer)#
-
-Sets the value of the future indicate by the key to the given pointer.
-All the threads waiting for the future specified by the key are
-awakened. (Each such thread, when it resumes, will return from the
-waitFuture function with the \verb#pointer# as its return value.)
-
-{\large \bf sendToFuture}
-
-\verb#sendToFuture(void *m, int key)#
-
-Makes an entry in the scheduler's queue that will (when scheduled) set
-the future value, and awaken the waiting threads. This is an
-asynchronous version of \verb#setFuture#. 
-
-
-{\large \bf  waitFuture}
-
-\verb#void* waitFuture (int key, int free)#
-
-The caller for this function must be a thread. If the future value is
-ready (i.e. set by \verb#setFuture# or \verb#sendToFuture#), the
-function returns immediately with a pointer to the value. Otherwise,
-the calling thread suspends, and the call returns after another thread
-has set the future value. This call can be made before or after the future
-is set.
-
-destroyFuture(int key)
-
-Allows  the key to be used for other futures.
-
-{\large \bf Bugs:} Currently, the number of futures is limited to 100.
-Although you can reuse a key with destroyFuture, this limits the
-number of futures alive at a time to 100. With a hash table
-implementation this could be completely eliminated in a future
-release, or at least an ability to change the number of available keys
-at the initialization time will be added.
-
-\end{document}
diff --git a/src/lib-misc/futures.c b/src/lib-misc/futures.c
deleted file mode 100644 (file)
index a766237..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*this module provides simple sequential functions that (help) implement
-the "Futures" abstraction.  Creating a new future simply returns an integer,
-after creating an internal data structure.  Two additional functions are 
-provided: one to set the value of the future, and another to wait for the
-future to be available.  The latter (waiting) function should be called
-only from a thread.  It returns with the value of the future (a void*)
-if it is already available.  Otherwise, it suspends until the future is
-available, an then returns with its value.  Multiple threads may wait for
-the same future.  The future is freed year via an explicit call, or by
-setting a parameter during the wait call. */
-
-#include <converse.h>
-
-#define  FREE  0
-#define WAITING 1
-#define AVAILABLE 2
-#define NULL 0
-
-typedef struct elt {
-  /*struct elt */ void * next;
-  CthThread t;
-} Element;
-
-typedef struct {
-  int ready; /* 0: free; 1: waiting; 2: available */
-  void *value;
-  Element *waiters;
-  int count;/* optional.  Reference count. */
-} Future;
-Future* futures;  /* Array of futures*/
-  int size =  100;
-/* change these to  csv later */
-
-CsvDeclare(int, futuresHandler);
-
-sendToFuture(void *m, int key)
-{
-*((int *) m ) =  CsvAccess(futuresHandler);
-*((int *) ((char *)m + CmiMsgHeaderSizeBytes)) = key;
-}
-
-
-void setFutureHandler (void *m)
-{
-CmiGrabBuffer(m);
-setFuture( *((int *) ((char *)m + CmiMsgHeaderSizeBytes)), m);
-}
-
-
-/* Futures abstraction */
-
-futuresInitialize()
-{ 
-  int i;
-  futures =  CmiAlloc( size*sizeof(Future ) );
-  /*  register the handler */
-  for (i=0; i<size; i++ )
-    { futures[ i].ready = FREE;
-    futures[ i].waiters = NULL;
-    }
-  CsvAccess(futuresHandler) = CmiRegisterHandler(setFutureHandler);
-}
-
-int createFuture()
-{
-int i;
-if (!futures) futuresInitialize ();
-for (i=0; i<size; i++ )
-  if (futures[ i].ready == FREE) break;
-
-if (i==size) { CmiPrintf(" future creation failed.\n"); return (-1); }
-futures[ i].ready = WAITING;
-futures[ i].waiters = NULL;
-return(i);
-
-}
-
-int destroyFuture(int key)
-     /* this function added on 7/22/97. -- sanjay */
-{
-  futures[key].ready = FREE;
-  futures[key].waiters = NULL;
-  CmiFree(futures[key].value);
-  futures[key].value = NULL;
-
-}
-
-static void* reallyWait (int key)
-  {
-     Element* e = (Element *) CmiAlloc(sizeof (Element) );
-
-     e->next =  futures[ key].waiters;
-     e->t = CthSelf();
-     futures[ key].waiters = e;
-     CthSuspend();
-     return( futures[ key].value);
-  }
-
-static void awaken_threads (Element *e)
-  {  Element *f;
-    while (e)
-      {
-/* CmiPrintf("[%d] Awakening next thread\n",CmiMyPe()); */
-       CthAwaken(e->t);
-       f = e;
-       e = e->next;
-       CmiFree( f);
-      }
-  }
-
-
-setFuture(int key, void*pointer)
-  {
-    if (!futures) futuresInitialize ();
-    futures[ key].ready = AVAILABLE;
-    futures[ key].value = pointer;
-
-    awaken_threads (futures[ key].waiters);
-    CmiPrintf(" [%d] awakened them\n",CmiMyPe());
-  }
-
-void* waitFuture (int key, int free)
-  {
-    static void* reallyWait ();
-    if (!futures) futuresInitialize ();
-
-    if (futures[ key].ready == AVAILABLE) {
-      if (free)   {
-        futures[ key].ready = FREE;
-      }
-      /*      if (--count == 0)  free the record.*/
-      return(futures[ key].value);
-    }
-    else {
-      /* insert thread in queue and Suspend thread */
-       return (reallyWait (key));
-    }
-  }
-