make multicore version PERT benchmark work on RAW(without interruption)
[IRC.git] / Robust / src / Runtime / thread.c
index d5f195e8604fc396d3d4c5c4e2badcdc454e15d4..a737e8df5a31853983fe45d738ad0a3e4f9c4978 100644 (file)
@@ -9,22 +9,27 @@
 #include <DSTM/interface/dstm.h>
 #include <DSTM/interface/llookup.h>
 
+#ifndef RAW
 #include <stdio.h>
+#endif
 int threadcount;
 pthread_mutex_t gclock;
 pthread_mutex_t gclistlock;
 pthread_cond_t gccond;
 pthread_mutex_t objlock;
 pthread_cond_t objcond;
+
+pthread_mutex_t joinlock;
+pthread_cond_t joincond;
 pthread_key_t threadlocks;
 pthread_mutex_t threadnotifylock;
 pthread_cond_t threadnotifycond;
-transrecord_t * trans;
 pthread_key_t oidval;
 
 void threadexit() {
   objheader_t* ptr;
   void *value;
+  transrecord_t * trans;
   unsigned int oidvalue;
 
 #ifdef THREADS
@@ -51,13 +56,15 @@ void threadexit() {
   oidvalue = *((unsigned int *)value);
   goto transstart;
 transstart:
-  trans = transStart();
-  ptr = transRead(trans, oidvalue);
-  struct ___Thread___ *p = (struct ___Thread___ *) ptr;
-  p->___threadDone___ = 1;
-  *((unsigned int *)&((struct ___Object___ *) p)->___localcopy___) |=DIRTY;
-  if(transCommit(trans) != 0) {
-         goto transstart;
+  {
+    transrecord_t * trans = transStart();
+    ptr = transRead(trans, oidvalue);
+    struct ___Thread___ *p = (struct ___Thread___ *) ptr;
+    p->___threadDone___ = 1;
+    *((unsigned int *)&((struct ___Object___ *) p)->___localcopy___) |=DIRTY;
+    if(transCommit(trans) != 0) {
+      goto transstart;
+    }
   }
 #endif 
   pthread_exit(NULL);
@@ -79,6 +86,8 @@ void initializethreads() {
   pthread_cond_init(&gccond, NULL);
   pthread_mutex_init(&objlock,NULL);
   pthread_cond_init(&objcond,NULL);
+  pthread_mutex_init(&joinlock,NULL);
+  pthread_cond_init(&joincond,NULL);
   pthread_key_create(&threadlocks, NULL);
   processOptions();
   initializeexithandler();
@@ -97,11 +106,17 @@ void initializethreads() {
 #ifdef THREADS
 void initthread(struct ___Thread___ * ___this___) {
 #ifdef PRECISE_GC
-  struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
-  ___Thread______staticStart____L___Thread___(&p);
+  int p[]={1, (int) NULL, (int) ___this___};
+  ___Thread______staticStart____L___Thread___((struct ___Thread______staticStart____L___Thread____params *)p);
+  ___this___=(struct ___Thread___ *) p[2];
 #else
   ___Thread______staticStart____L___Thread___(___this___);
 #endif
+  ___this___->___finished___=1;
+  pthread_mutex_lock(&joinlock);
+  pthread_cond_signal(&joincond);
+  pthread_mutex_unlock(&joinlock);
+
   pthread_mutex_lock(&gclistlock);
   threadcount--;
   pthread_cond_signal(&gccond);
@@ -123,15 +138,21 @@ void CALL11(___Thread______sleep____J, long long ___millis___, long long ___mill
 #endif
 }
 
+#if defined(DSTM)||defined(THREADS)
+void CALL00(___Thread______yield____) {
+  pthread_yield();
+}
+#endif
+
 #ifdef DSTM
 /* Add thread join capability */
 void CALL01(___Thread______join____, struct ___Thread___ * ___this___) {
-  pthread_t thread;
   unsigned int *oidarray;
   unsigned short *versionarray, version;
   transrecord_t *trans;
   objheader_t *ptr;
   /* Add transaction to check if thread finished for join operation */
+  goto transstart;
 transstart:
   trans = transStart();
   ptr = transRead(trans, (unsigned int) VAR(___this___));
@@ -140,6 +161,7 @@ transstart:
          transAbort(trans);
          return;
   } else {
+
          version = (ptr-1)->version;
          if((oidarray = calloc(1, sizeof(unsigned int))) == NULL) {
                  printf("Calloc error %s, %d\n", __FILE__, __LINE__);
@@ -155,7 +177,13 @@ transstart:
          }
          versionarray[0] = version;
          /* Request Notification */
+#ifdef PRECISE_GC
+         struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
+#endif
          reqNotify(oidarray, versionarray, 1); 
+#ifdef PRECISE_GC
+         restartaftergc(tmp);
+#endif
          free(oidarray);
          free(versionarray);
          transAbort(trans);
@@ -166,6 +194,13 @@ transstart:
 #endif
 
 #ifdef THREADS
+void CALL01(___Thread______nativeJoin____, struct ___Thread___ * ___this___) {
+  pthread_mutex_lock(&joinlock);
+  while(!VAR(___this___)->___finished___)
+    pthread_cond_wait(&joincond, &joinlock);
+  pthread_mutex_unlock(&joinlock);  
+}
+
 void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
   pthread_t thread;
   int retval;
@@ -182,6 +217,7 @@ void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
     if (retval!=0)
       usleep(1);
   } while(retval!=0);
+  /* This next statement will likely not work on many machines */
 
   pthread_attr_destroy(&nattr);
 }
@@ -201,6 +237,7 @@ void globalDestructor(void *value) {
 
 void initDSMthread(int *ptr) {
   objheader_t *tmp;    
+  transrecord_t * trans;
   void *threadData;
   int oid=ptr[0];
   int type=ptr[1];
@@ -221,12 +258,14 @@ void initDSMthread(int *ptr) {
   /* Add transaction to check if thread finished for join operation */
   goto transstart;
 transstart:
-  trans = transStart();
-  tmp  = transRead(trans, (unsigned int) oid);
-  ((struct ___Thread___ *)tmp)->___threadDone___ = 1;
-  *((unsigned int *)&((struct ___Object___ *) tmp)->___localcopy___) |=DIRTY;
-  if(transCommit(trans)!= 0) {
-         goto transstart;
+  {
+    transrecord_t * trans = transStart();
+    tmp  = transRead(trans, (unsigned int) oid);
+    ((struct ___Thread___ *)tmp)->___threadDone___ = 1;
+    *((unsigned int *)&((struct ___Object___ *) tmp)->___localcopy___) |=DIRTY;
+    if(transCommit(trans)!= 0) {
+      goto transstart;
+    }
   }
   pthread_exit(NULL);
 }