drop locks if a thread crashes
authorbdemsky <bdemsky>
Wed, 21 Feb 2007 05:38:34 +0000 (05:38 +0000)
committerbdemsky <bdemsky>
Wed, 21 Feb 2007 05:38:34 +0000 (05:38 +0000)
Robust/src/Benchmarks/WebServerJava/Inventory.java
Robust/src/ClassLibrary/ObjectJava.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/Runtime/garbage.c
Robust/src/Runtime/garbage.h
Robust/src/Runtime/object.c
Robust/src/Runtime/runtime.c
Robust/src/Runtime/thread.c
Robust/src/Runtime/thread.h

index fafc29c08f43b2e7d6e51d3db76054cf1ed02f05..5755b7396d6c9dbe58bb205ef648f659d1f19c7a 100644 (file)
@@ -18,7 +18,7 @@ public class Inventory {
        }
 
        // Add item to a list of inventory
-       public int additem(String name, int quantity, int price){
+       public synchronized int additem(String name, int quantity, int price){
                ItemInfo newitem = new ItemInfo(quantity, price);
                // Get the item from hash
                if (map.containsKey(name) == false) {
@@ -33,7 +33,7 @@ public class Inventory {
        }       
 
        // Buy item from a given list of inventory      
-       public int buyitem(String name, int quantity){
+       public synchronized int buyitem(String name, int quantity){
                if (map.containsKey(name) == false) {
        //              System.printString("Error - Item does not exist");
                        return -1;
@@ -56,7 +56,7 @@ public class Inventory {
        }
 
        //Display the inventory list
-       public String inventory(){
+       public synchronized String inventory(){
                HashMapIterator i = new HashMapIterator(map, 0);// Gets key from the hashmap= name of item
                HashMapIterator j = new HashMapIterator(map, 1);//Gets the value from hashmap 
                StringBuffer sb = new StringBuffer("");
index 89d8686ddfd318bee8b207f24d2d05bff99be082..274d6490175cd4159d94a9d1cdfe8c0b77716e06 100644 (file)
@@ -1,5 +1,8 @@
 public class Object {
     public native int hashCode();
+    private Object nextlockobject;
+    private Object prevlockobject;
+
 
     /* DON'T USE THIS METHOD UNLESS NECESSARY */
     /* WE WILL DEPRECATE IT AS SOON AS INSTANCEOF WORKS */
index 1e5c92912f6abce477171b0900aef2351c98aa06..fe62e698acf6340fc380c732aa5b7f7d00583a09 100644 (file)
@@ -124,6 +124,7 @@ public class BuildCode {
            outclassdefs.println("  int type;");
            if (state.THREAD) {
                outclassdefs.println("  pthread_t tid;");
+               outclassdefs.println("  void * lockentry;");
                outclassdefs.println("  int lockcount;");
            }
                
@@ -729,6 +730,7 @@ public class BuildCode {
        classdefout.println("  int type;");
        if (state.THREAD) {
            classdefout.println("  pthread_t tid;");
+           classdefout.println("  void * lockentry;");
            classdefout.println("  int lockcount;");
        }
 
index 8b8d7370067fceca3779e8c781bea1cc6ec23fb9..4fced6a9393ff0e6ac79e875bd4f12d6847ad5ba 100644 (file)
@@ -115,6 +115,11 @@ void collect(struct garbagelist * stackptr) {
 #ifdef THREADS
   /* Go to next thread */
   if (listptr!=NULL) {
+    void * orig=listptr->locklist;
+    void * copy;
+    if (gc_createcopy(orig,&copy))
+      enqueue(orig);
+    listptr->locklist=copy;
     stackptr=listptr->stackptr;
     listptr=listptr->next;
   }
@@ -292,6 +297,7 @@ void checkcollect(void * ptr) {
 struct listitem * stopforgc(struct garbagelist * ptr) {
   struct listitem * litem=malloc(sizeof(struct listitem));
   litem->stackptr=ptr;
+  litem->locklist=pthread_getspecific(threadlocks);
   litem->prev=NULL;
   pthread_mutex_lock(&gclistlock);
   litem->next=list;
@@ -306,6 +312,7 @@ struct listitem * stopforgc(struct garbagelist * ptr) {
 
 void restartaftergc(struct listitem * litem) {
   pthread_mutex_lock(&gclistlock);
+  pthread_setspecific(threadlocks, litem->locklist);
   if (litem->prev==NULL) {
     list=litem->next;
   } else {
index 80171a58825ba7d75222ff1cf332a60ae4528c53..ee5b79ec80fc1677f9e004eef11adf561a7a708e 100644 (file)
@@ -10,6 +10,7 @@ struct listitem {
   struct listitem * prev;
   struct listitem * next;
   struct garbagelist * stackptr;
+  struct ___Object___ * locklist;
 };
 
 #ifdef THREADS
index 352637d10e7a019fce3cb936fa3d4e0aea050be1..8cf5ae62652a03e2cbb01a1a91edbd3d3298bd4c 100644 (file)
@@ -29,6 +29,10 @@ int CALL01(___Object______MonitorEnter____, struct ___Object___ * ___this___) {
 #endif
     while(1) {
       if (VAR(___this___)->tid==0) {
+       VAR(___this___)->___prevlockobject___=NULL;
+       VAR(___this___)->___nextlockobject___=(struct ___Object___ *)pthread_getspecific(threadlocks);
+       VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___);
+       pthread_setspecific(threadlocks, VAR(___this___));
        VAR(___this___)->lockcount=1;
        VAR(___this___)->tid=self;
        pthread_mutex_unlock(&objlock);
@@ -51,8 +55,16 @@ int CALL01(___Object______MonitorExit____, struct ___Object___ * ___this___) {
   pthread_t self=pthread_self();
   if (self==VAR(___this___)->tid) {
     VAR(___this___)->lockcount--;
-    if (VAR(___this___)->lockcount==0)
+    if (VAR(___this___)->lockcount==0) {
+      if (VAR(___this___)->___prevlockobject___==NULL) {
+       pthread_setspecific(threadlocks, VAR(___this___)->___nextlockobject___);
+      } else
+       VAR(___this___)->___prevlockobject___->___nextlockobject___=VAR(___this___)->___nextlockobject___;
+      if (VAR(___this___)->___nextlockobject___!=NULL)
+       VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___)->___prevlockobject___;
+      VAR(___this___)->lockentry=NULL;
       VAR(___this___)->tid=0;
+    }
     pthread_mutex_lock(&objlock);
     pthread_cond_broadcast(&objcond);
     pthread_mutex_unlock(&objlock);
index f45c1be8f1410a88871beb1468b785705eaf8908..70a5215861e15523c6465db9121580295318e736 100644 (file)
@@ -432,6 +432,7 @@ void * allocate_new(void * ptr, int type) {
   v->type=type;
 #ifdef THREADS
   v->tid=0;
+  v->lockentry=0;
   v->lockcount=0;
 #endif
   return v;
@@ -445,6 +446,7 @@ struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
   v->___length___=length;
 #ifdef THREADS
   v->tid=0;
+  v->lockentry=0;
   v->lockcount=0;
 #endif
   return v;
@@ -496,7 +498,11 @@ struct ___String___ * NewString(const char *str,int length) {
 void failedboundschk() {
 #ifndef TASK
   printf("Array out of bounds\n");
+#ifdef THREADS
+  threadexit();
+#else
   exit(-1);
+#endif
 #else
   longjmp(error_handler,2);
 #endif
index 2f745651e5d1f355ad9ddcc73fcefe0a67188c25..54cb32b7d62fb08ee50edd509e99d33512ce7989 100644 (file)
@@ -13,14 +13,50 @@ pthread_mutex_t gclistlock;
 pthread_cond_t gccond;
 pthread_mutex_t objlock;
 pthread_cond_t objcond;
+pthread_key_t threadlocks;
+
+void threadexit() {
+  struct ___Object___ *ll=pthread_getspecific(threadlocks);
+  while(ll!=NULL) {
+    struct ___Object___ *llnext=ll->___nextlockobject___;    
+    ll->___nextlockobject___=NULL;
+    ll->___prevlockobject___=NULL;
+    ll->lockcount=0;
+    ll->tid=0; //unlock it
+    ll=llnext;
+  }
+  pthread_mutex_lock(&objlock);//wake everyone up
+  pthread_cond_broadcast(&objcond);
+  pthread_mutex_unlock(&objlock);
+  pthread_exit(NULL);
+}
+
+void threadhandler(int sig, siginfo_t *info, void *uap) {
+#ifdef DEBUG
+  printf("sig=%d\n",sig);
+  printf("signal\n");
+#endif
+  threadexit();
+}
 
 void initializethreads() {
+  struct sigaction sig;
   threadcount=1;
   pthread_mutex_init(&gclock, NULL);
   pthread_mutex_init(&gclistlock, NULL);
   pthread_cond_init(&gccond, NULL);
   pthread_mutex_init(&objlock,NULL);
   pthread_cond_init(&objcond,NULL);
+  pthread_key_create(&threadlocks, NULL);
+
+  sig.sa_sigaction=&threadhandler;
+  sig.sa_flags=SA_SIGINFO;
+  sigemptyset(&sig.sa_mask);
+
+  /* Catch bus errors, segmentation faults, and floating point exceptions*/
+  sigaction(SIGBUS,&sig,0);
+  sigaction(SIGSEGV,&sig,0);
+  sigaction(SIGFPE,&sig,0);
 }
 
 void initthread(struct ___Thread___ * ___this___) {
index e12a8e061a62fc19420774cf8442198462a2bee4..0062c6bcc120d7962c81b1bab305c06dd1710dbd 100644 (file)
@@ -9,5 +9,12 @@ extern pthread_mutex_t gclistlock;
 extern pthread_cond_t gccond;
 extern pthread_mutex_t objlock;
 extern pthread_cond_t objcond;
+extern pthread_key_t threadlocks;
 void initthread(struct ___Thread___ * ___this___);
+
+struct locklist {
+  struct locklist * next;
+  struct locklist * prev;
+  struct ___Object___ * object;
+};
 #endif