d2f6041f311b69a2d235659ebbd580dabd3a84f2
[IRC.git] / Robust / src / Runtime / STM / inlinestm.h
1 #ifndef INLINESTM_H
2 #define INLINESTM_H
3 #if defined(DELAYCOMP)&&(!defined(STMARRAY)||defined(DUALVIEW))
4
5 #ifndef READSET
6 #define CHECKREADS(x) 0
7 #endif
8
9 #ifdef TRANSSTATS
10 #define TRANSWRAP(x) x
11 #else
12 #define TRANSWRAP(x)
13 #endif
14
15 #define LIGHTWEIGHTCOMMIT(commitmethod, primitives, locals, params, label) \
16   if (GETLOCKS()||CHECKREADS()) {                                       \
17     TRANSWRAP(numTransAbort++;);                                        \
18     if (unlikely(needtocollect)) checkcollect(&___locals___);           \
19     goto label;                                                         \
20   }                                                                     \
21   ptrstack.maxcount=0;                                                  \
22   primstack.count=0;                                                    \
23   branchstack.count=0;                                                  \
24   commitmethod(params, locals, primitives);                             \
25   RELEASELOCKS();                                                       \
26   FREELIST();                                                           \
27   TRANSWRAP(numTransCommit++;);
28
29
30 #ifdef READSET
31 static inline int CHECKREADS() {
32   rdchashlistnode_t *rd_curr=rd_c_list;
33   int retval=0;
34   rdchashlistnode_t *ptr=rd_c_table;
35   rdchashlistnode_t *top=&ptr[rd_c_size];
36
37   while(likely(rd_curr!=NULL)) {
38     unsigned int version=rd_curr->version;
39     struct ___Object___ * objptr=rd_curr->key;
40     objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t));
41     if(likely(header->lock>0)) {//doesn't matter what type of lock...
42       if(unlikely(version!=header->version)) {
43         retval=1;break;
44       }
45     } else {
46       if(likely(version==header->version)) {
47         dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)objptr) & dc_c_mask)>>4];
48         do {
49           if(node->key == objptr) {
50             goto nextloop;
51           }
52           node = node->next;
53         } while(node!=NULL);
54         retval=1;break;
55       }
56     }
57   nextloop:
58     if (likely(rd_curr>=ptr&&rd_curr<top)) {
59       //zero in list
60       rd_curr->key=NULL;
61       rd_curr->next=NULL;
62     }
63     rd_curr=rd_curr->lnext;
64   }
65
66   if (unlikely(retval)) {
67     while(likely(rd_curr!=NULL)) {
68       if (likely(rd_curr>=ptr&&rd_curr<top)) {
69         //zero in list
70         rd_curr->key=NULL;
71         rd_curr->next=NULL;
72       }
73       rd_curr=rd_curr->lnext;
74     }
75     while(rd_c_structs->next!=NULL) {
76       rdcliststruct_t *next=rd_c_structs->next;
77       free(rd_c_structs);
78       rd_c_structs=next;
79     }
80     rd_c_structs->num = 0;
81     rd_c_numelements = 0;
82     rd_c_list=NULL;
83     
84     lwreset(NULL);
85     return 1;
86   }
87
88   while(rd_c_structs->next!=NULL) {
89     rdcliststruct_t *next=rd_c_structs->next;
90     free(rd_c_structs);
91     rd_c_structs=next;
92   }
93   rd_c_structs->num = 0;
94   rd_c_numelements = 0;
95   rd_c_list=NULL;
96
97   return 0;
98 }
99 #endif
100
101 static inline void FREELIST() {
102   dchashlistnode_t *ptr = dc_c_table;
103   dchashlistnode_t *top=&ptr[dc_c_size];
104   dchashlistnode_t *tmpptr=dc_c_list;
105   while(tmpptr!=NULL) {
106     dchashlistnode_t *next=tmpptr->lnext;
107     if (tmpptr>=ptr&&tmpptr<top) {
108       /*zero in list    */
109       tmpptr->key=NULL;
110       tmpptr->next=NULL;
111     }
112     tmpptr=next;
113   }
114   while(dc_c_structs->next!=NULL) {
115     dcliststruct_t *next=dc_c_structs->next;
116     free(dc_c_structs);
117     dc_c_structs=next;
118   }
119   dc_c_structs->num = 0;
120   dc_c_numelements = 0;
121   dc_c_list=NULL;
122 }
123
124 static inline void RELEASELOCKS() {
125   dchashlistnode_t *dc_curr = dc_c_list;
126   while(likely(dc_curr!=NULL)) {
127     struct ___Object___ * objptr=dc_curr->key;
128     objheader_t *header=&((objheader_t *)objptr)[-1];
129 #ifdef STMARRAY
130     if (objptr->type>=NUMCLASSES) {
131       ((struct ArrayObject *)objptr)->arrayversion++;
132       header->version++;
133       rwwrite_unlock(&header->lock);
134     } else {
135 #endif
136       header->version++;
137       write_unlock(&header->lock);
138 #ifdef STMARRAY
139     }
140 #endif
141     dc_curr=dc_curr->lnext;
142   }
143   primstack.count=0;
144   ptrstack.count=0;
145   branchstack.count=0;                                
146 }
147
148 static inline int GETLOCKS() {
149   dchashlistnode_t *dc_curr = dc_c_list;
150   while(likely(dc_curr!=NULL)) {
151     struct ___Object___ * objptr=dc_curr->key;
152     objheader_t *header=&((objheader_t *)objptr)[-1];
153 #ifdef STMARRAY
154     if (objptr->type>=NUMCLASSES) {
155       if (unlikely(!rwwrite_trylock(&header->lock))) {
156 #ifdef READSET
157         rd_t_chashreset();
158 #endif
159         lwreset(dc_curr);
160         return 1;
161       }
162     } else 
163 #endif
164     if(unlikely(!write_trylock(&header->lock))) {
165 #ifdef READSET
166       rd_t_chashreset();
167 #endif
168       lwreset(dc_curr);
169       return 1;
170     }
171     dc_curr=dc_curr->lnext;
172   }
173   return 0;
174 }
175
176 #endif
177 #endif