From 608946d7742d6945ae1606ccf4a57749212fa140 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Wed, 21 Feb 2007 05:38:34 +0000 Subject: [PATCH] drop locks if a thread crashes --- .../Benchmarks/WebServerJava/Inventory.java | 6 ++-- Robust/src/ClassLibrary/ObjectJava.java | 3 ++ Robust/src/IR/Flat/BuildCode.java | 2 ++ Robust/src/Runtime/garbage.c | 7 ++++ Robust/src/Runtime/garbage.h | 1 + Robust/src/Runtime/object.c | 14 +++++++- Robust/src/Runtime/runtime.c | 6 ++++ Robust/src/Runtime/thread.c | 36 +++++++++++++++++++ Robust/src/Runtime/thread.h | 7 ++++ 9 files changed, 78 insertions(+), 4 deletions(-) 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,©)) + 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 -- 2.34.1