From: bdemsky <bdemsky>
Date: Wed, 21 Feb 2007 05:38:34 +0000 (+0000)
Subject: drop locks if a thread crashes
X-Git-Tag: preEdgeChange~709
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=608946d7742d6945ae1606ccf4a57749212fa140;p=IRC.git

drop locks if a thread crashes
---

diff --git a/Robust/src/Benchmarks/WebServerJava/Inventory.java b/Robust/src/Benchmarks/WebServerJava/Inventory.java
index fafc29c0..5755b739 100644
--- a/Robust/src/Benchmarks/WebServerJava/Inventory.java
+++ b/Robust/src/Benchmarks/WebServerJava/Inventory.java
@@ -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("");
diff --git a/Robust/src/ClassLibrary/ObjectJava.java b/Robust/src/ClassLibrary/ObjectJava.java
index 89d8686d..274d6490 100644
--- a/Robust/src/ClassLibrary/ObjectJava.java
+++ b/Robust/src/ClassLibrary/ObjectJava.java
@@ -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 */
diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java
index 1e5c9291..fe62e698 100644
--- a/Robust/src/IR/Flat/BuildCode.java
+++ b/Robust/src/IR/Flat/BuildCode.java
@@ -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;");
 	}
 
diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c
index 8b8d7370..4fced6a9 100644
--- a/Robust/src/Runtime/garbage.c
+++ b/Robust/src/Runtime/garbage.c
@@ -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 {
diff --git a/Robust/src/Runtime/garbage.h b/Robust/src/Runtime/garbage.h
index 80171a58..ee5b79ec 100644
--- a/Robust/src/Runtime/garbage.h
+++ b/Robust/src/Runtime/garbage.h
@@ -10,6 +10,7 @@ struct listitem {
   struct listitem * prev;
   struct listitem * next;
   struct garbagelist * stackptr;
+  struct ___Object___ * locklist;
 };
 
 #ifdef THREADS
diff --git a/Robust/src/Runtime/object.c b/Robust/src/Runtime/object.c
index 352637d1..8cf5ae62 100644
--- a/Robust/src/Runtime/object.c
+++ b/Robust/src/Runtime/object.c
@@ -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);
diff --git a/Robust/src/Runtime/runtime.c b/Robust/src/Runtime/runtime.c
index f45c1be8..70a52158 100644
--- a/Robust/src/Runtime/runtime.c
+++ b/Robust/src/Runtime/runtime.c
@@ -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
diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c
index 2f745651..54cb32b7 100644
--- a/Robust/src/Runtime/thread.c
+++ b/Robust/src/Runtime/thread.c
@@ -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___) {
diff --git a/Robust/src/Runtime/thread.h b/Robust/src/Runtime/thread.h
index e12a8e06..0062c6bc 100644
--- a/Robust/src/Runtime/thread.h
+++ b/Robust/src/Runtime/thread.h
@@ -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