Changes
[IRC.git] / Robust / src / Runtime / object.c
1 #include "object.h"
2 #ifdef MULTICORE
3 #include "runtime_arch.h"
4 #else
5 #include "stdio.h"
6 #endif
7 #include "stdlib.h"
8
9 #ifdef THREADS
10 #include "thread.h"
11 #endif
12 #ifndef MULTICORE
13 #include "mlp_lock.h"
14 #endif
15
16 #ifdef D___Object______nativehashCode____
17 int CALL01(___Object______nativehashCode____, struct ___Object___ * ___this___) {
18   return (int)((INTPTR) VAR(___this___));
19 }
20 #endif
21
22 #ifdef D___Object______hashCode____
23 int CALL01(___Object______hashCode____, struct ___Object___ * ___this___) {
24   if (!VAR(___this___)->___cachedHash___) {
25     VAR(___this___)->___cachedHash___=1;
26     VAR(___this___)->___cachedCode___=(int)((INTPTR)VAR(___this___));
27   }
28   return VAR(___this___)->___cachedCode___;
29 }
30 #endif
31
32 int CALL01(___Object______getType____, struct ___Object___ * ___this___) {
33   return ((int *)VAR(___this___))[0];
34 }
35
36 #ifdef THREADS
37 int CALL01(___Object______MonitorEnter____, struct ___Object___ * ___this___) {
38 #ifndef NOLOCK
39   pthread_t self=pthread_self();
40   if (self==VAR(___this___)->tid) {
41     atomic_inc(&VAR(___this___)->lockcount);
42   } else {
43     while(1) {
44       if (CAS32(&VAR(___this___)->lockcount, 0, 1)==0) {
45         VAR(___this___)->___prevlockobject___=NULL;
46         VAR(___this___)->___nextlockobject___=(struct ___Object___ *)pthread_getspecific(threadlocks);
47         if (VAR(___this___)->___nextlockobject___!=NULL)
48           VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___);
49         pthread_setspecific(threadlocks, VAR(___this___));
50         VAR(___this___)->tid=self;
51         pthread_mutex_unlock(&objlock);
52         BARRIER();
53         return;
54       }
55       {
56 #ifdef PRECISE_GC
57         stopforgc((struct garbagelist *)___params___);
58 #endif
59 #ifdef PRECISE_GC
60         restartaftergc();
61 #endif
62       }
63     }
64   }
65 #endif
66 }
67
68 #ifdef D___Object______notify____
69 void CALL01(___Object______notify____, struct ___Object___ * ___this___) {
70 }
71 #endif
72 #ifdef D___Object______notifyAll____
73 void CALL01(___Object______notifyAll____, struct ___Object___ * ___this___) {
74 }
75 #endif
76 #ifdef D___Object______wait____
77 void CALL01(___Object______wait____, struct ___Object___ * ___this___) {
78   pthread_t self=pthread_self();
79   int lockcount=VAR(___this___)->lockcount;
80   //release lock
81   if (VAR(___this___)->___prevlockobject___==NULL) {
82     pthread_setspecific(threadlocks, VAR(___this___)->___nextlockobject___);
83   } else
84     VAR(___this___)->___prevlockobject___->___nextlockobject___=VAR(___this___)->___nextlockobject___;
85   if (VAR(___this___)->___nextlockobject___!=NULL)
86     VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___)->___prevlockobject___;
87   VAR(___this___)->___nextlockobject___=NULL;
88   VAR(___this___)->___prevlockobject___=NULL;
89   //VAR(___this___)->lockentry=NULL;
90   VAR(___this___)->tid=0;
91   //release lock
92   BARRIER();
93   VAR(___this___)->lockcount=0;
94   
95   //allow gc
96 #ifdef PRECISE_GC
97   stopforgc((struct garbagelist *)___params___);
98 #endif
99   sched_yield();
100 #ifdef PRECISE_GC
101   restartaftergc();
102 #endif
103
104   while(1) {
105     if (CAS32(&VAR(___this___)->lockcount, 0, lockcount)==0) {
106       VAR(___this___)->___prevlockobject___=NULL;
107       VAR(___this___)->___nextlockobject___=(struct ___Object___ *)pthread_getspecific(threadlocks);
108       if (VAR(___this___)->___nextlockobject___!=NULL)
109         VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___);
110       pthread_setspecific(threadlocks, VAR(___this___));
111       VAR(___this___)->tid=self;
112       pthread_mutex_unlock(&objlock);
113       BARRIER();
114       return;
115     }
116     {
117 #ifdef PRECISE_GC
118       stopforgc((struct garbagelist *)___params___);
119 #endif
120 #ifdef PRECISE_GC
121       restartaftergc();
122 #endif
123     }
124   }
125 }
126 #endif
127
128 int CALL01(___Object______MonitorExit____, struct ___Object___ * ___this___) {
129 #ifndef NOLOCK
130   pthread_t self=pthread_self();
131   if (self==VAR(___this___)->tid) {
132     //release one lock...
133     BARRIER();
134     if (VAR(___this___)->lockcount==1) {
135       if (VAR(___this___)->___prevlockobject___==NULL) {
136         pthread_setspecific(threadlocks, VAR(___this___)->___nextlockobject___);
137       } else
138         VAR(___this___)->___prevlockobject___->___nextlockobject___=VAR(___this___)->___nextlockobject___;
139       if (VAR(___this___)->___nextlockobject___!=NULL)
140         VAR(___this___)->___nextlockobject___->___prevlockobject___=VAR(___this___)->___prevlockobject___;
141       VAR(___this___)->___nextlockobject___=NULL;
142       VAR(___this___)->___prevlockobject___=NULL;
143       //VAR(___this___)->lockentry=NULL;
144       VAR(___this___)->tid=0;
145     }
146     atomic_dec(&VAR(___this___)->lockcount);
147   } else {
148 #ifdef MULTICORE
149     BAMBOO_EXIT(0xf201);
150 #else
151     printf("ERROR...UNLOCKING LOCK WE DON'T HAVE\n");
152     exit(-1);
153 #endif
154   }
155 #endif
156 }
157 #endif