Initial thread join modifications
[IRC.git] / Robust / src / Runtime / thread.c
1 #include "runtime.h"
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <stdlib.h>
6 #include "thread.h"
7 #include "option.h"
8 #include <signal.h>
9 #include <DSTM/interface/dstm.h>
10
11 #include <stdio.h>
12 int threadcount;
13 pthread_mutex_t gclock;
14 pthread_mutex_t gclistlock;
15 pthread_cond_t gccond;
16 pthread_mutex_t objlock;
17 pthread_cond_t objcond;
18 pthread_key_t threadlocks;
19 pthread_mutex_t threadnotifylock;
20 pthread_cond_t threadnotifycond;
21 transrecord_t * trans;
22
23 void threadexit() {
24   void *ptr;
25 #ifdef THREADS
26   struct ___Object___ *ll=pthread_getspecific(threadlocks);
27   while(ll!=NULL) {
28     struct ___Object___ *llnext=ll->___nextlockobject___;    
29     ll->___nextlockobject___=NULL;
30     ll->___prevlockobject___=NULL;
31     ll->lockcount=0;
32     ll->tid=0; //unlock it
33     ll=llnext;
34   }
35   pthread_mutex_lock(&objlock);//wake everyone up
36   pthread_cond_broadcast(&objcond);
37   pthread_mutex_unlock(&objlock);
38 #endif
39   pthread_mutex_lock(&gclistlock);
40   threadcount--;
41   pthread_cond_signal(&gccond);
42   pthread_mutex_unlock(&gclistlock);
43   /* Add transaction to check if thread finished for join operation */
44   goto transstart;
45 transretry:
46
47 transstart:
48         trans = transStart();
49         ptr  = (void *)transRead(trans, (unsigned int) a);
50         struct ___Thread___ *tmp = ((char *) ptr + sizeof(objheader_t));
51         tmp->___threadDone___ = 1;
52         if(transCommit(trans)) {
53                                         goto transretry;
54   } else {
55                                         COMMIT_OBJ();
56   }
57   pthread_exit(NULL);
58 }
59
60 void threadhandler(int sig, siginfo_t *info, void *uap) {
61 #ifdef DEBUG
62   printf("sig=%d\n",sig);
63   printf("signal\n");
64 #endif
65   threadexit();
66 }
67
68 void initializethreads() {
69   struct sigaction sig;
70   threadcount=1;
71   pthread_mutex_init(&gclock, NULL);
72   pthread_mutex_init(&gclistlock, NULL);
73   pthread_cond_init(&gccond, NULL);
74   pthread_mutex_init(&objlock,NULL);
75   pthread_cond_init(&objcond,NULL);
76   pthread_key_create(&threadlocks, NULL);
77   processOptions();
78   initializeexithandler();
79
80   sig.sa_sigaction=&threadhandler;
81   sig.sa_flags=SA_SIGINFO;
82   sigemptyset(&sig.sa_mask);
83
84   /* Catch bus errors, segmentation faults, and floating point exceptions*/
85   sigaction(SIGBUS,&sig,0);
86   sigaction(SIGSEGV,&sig,0);
87   sigaction(SIGFPE,&sig,0);
88   signal(SIGPIPE, SIG_IGN);
89 }
90
91 #ifdef THREADS
92 void initthread(struct ___Thread___ * ___this___) {
93 #ifdef PRECISE_GC
94   struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
95   ___Thread______staticStart____L___Thread___(&p);
96 #else
97   ___Thread______staticStart____L___Thread___(___this___);
98 #endif
99   pthread_mutex_lock(&gclistlock);
100   threadcount--;
101   pthread_cond_signal(&gccond);
102   pthread_mutex_unlock(&gclistlock);
103 }
104 #endif
105
106 void CALL11(___Thread______sleep____J, long long ___millis___, long long ___millis___) {
107 #ifdef THREADS
108 #ifdef PRECISE_GC
109   struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
110 #endif
111 #endif
112   usleep(___millis___);  
113 #ifdef THREADS
114 #ifdef PRECISE_GC
115   restartaftergc(tmp);
116 #endif
117 #endif
118 }
119
120 /* Add thread join capability */
121 #ifdef DSTM
122 void CALL01(___Thread______join____, struct ___Thread___ * ___this___) {
123   pthread_t thread;
124   printf("DEBUG -> Inside thread join\n");
125   int status;
126   if(VAR(___this___)->___threadDone___) {
127           return;
128   } else {
129           /* Request Notification */
130           pthread_cond_broadcast(&objcond);
131           pthread_mutex_unlock(&objlock);
132           pthread_mutex_lock(&threadnotifylock);//wake everyone up
133           status = reqNotify((unsigned int)VAR(___this___));
134           
135           if((status = reqNotify((unsigned int)VAR(___this___))) != 0) {
136                   printf("No notification is sent %s, %d\n", __FILE__, __LINE__);
137           } else {
138                   return;
139           }
140   }
141 }
142 #endif
143
144 #ifdef THREADS
145 void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
146   pthread_t thread;
147   int retval;
148   pthread_attr_t nattr;
149
150   pthread_mutex_lock(&gclistlock);
151   threadcount++;
152   pthread_mutex_unlock(&gclistlock);
153   pthread_attr_init(&nattr);
154   pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
155   
156   do {
157     retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initthread, VAR(___this___));
158     if (retval!=0)
159       usleep(1);
160   } while(retval!=0);
161
162   pthread_attr_destroy(&nattr);
163 }
164 #endif
165
166 #ifdef DSTM
167 void CALL12(___Thread______start____I, int ___mid___, struct ___Thread___ * ___this___, int ___mid___) {
168   startRemoteThread((unsigned int)VAR(___this___), ___mid___);
169 }
170 #endif
171
172 #ifdef DSTM
173 void initDSMthread(int *ptr) {
174   int oid=ptr[0];
175   int type=ptr[1];
176   free(ptr);
177 #ifdef PRECISE_GC
178   int p[]={1, 0 /* NULL */, oid};
179   ((void (*)(void *))virtualtable[type*MAXCOUNT+RUNMETHOD])(p);
180 #else
181   ((void (*)(void *))virtualtable[type*MAXCOUNT+RUNMETHOD])(oid);
182 #endif
183   pthread_mutex_lock(&gclistlock);
184         threadcount--;
185         pthread_cond_signal(&gccond);
186         pthread_mutex_unlock(&gclistlock);
187         /* Add transaction to check if thread finished for join operation */
188         goto transstart;
189 transretry:
190         //TODO
191
192 transstart:
193         trans = transStart();
194         ptr  = (void *)transRead(trans, (unsigned int) oid);
195         struct ___Thread___ *tmp = ((char *) ptr + sizeof(objheader_t));
196         tmp->___threadDone___ = 1;
197         if(transCommit(trans)) {
198                                         goto transretry;
199         } else {
200                                         //TODO
201         }
202 }
203
204 void startDSMthread(int oid, int objType) {
205   pthread_t thread;
206   int retval;
207   pthread_attr_t nattr;
208
209   pthread_mutex_lock(&gclistlock);
210   threadcount++;
211   pthread_mutex_unlock(&gclistlock);
212   pthread_attr_init(&nattr);
213   pthread_attr_setdetachstate(&nattr, PTHREAD_CREATE_DETACHED);
214   int * ptr=malloc(sizeof(int)*2);
215   ptr[0]=oid;
216   ptr[1]=objType;
217   do {
218     retval=pthread_create(&thread, &nattr, (void * (*)(void *)) &initDSMthread,  ptr);
219     if (retval!=0)
220       usleep(1);
221   } while(retval!=0);
222
223   pthread_attr_destroy(&nattr);
224 }
225
226 #endif