add more lock primitives
[IRC.git] / Robust / src / Runtime / STM / stm.c
1 /* ============================================================
2  * singleTMCommit.c
3  * - single thread commit on local machine
4  * =============================================================
5  * Copyright (c) 2009, University of California, Irvine, USA.
6  * All rights reserved.
7  * Author: Alokika Dash
8  *         adash@uci.edu
9  * =============================================================
10  *
11  */
12
13 #include "tm.h"
14 #include "garbage.h"
15
16 /* Per thread transaction variables */
17 __thread objstr_t *t_cache;
18 __thread objstr_t *t_reserve;
19 __thread struct objlist * newobjs;
20
21 #ifdef SANDBOX
22 #include "sandbox.h"
23 #endif
24
25 #ifdef DELAYCOMP
26 #include "delaycomp.h"
27 __thread struct pointerlist ptrstack;
28 __thread struct primitivelist primstack;
29 __thread struct branchlist branchstack;
30 struct pointerlist *c_ptrstack;
31 struct primitivelist *c_primstack;
32 struct branchlist *c_branchstack;
33 #endif
34
35 #ifdef TRANSSTATS
36 int numTransCommit = 0;
37 int numTransAbort = 0;
38 int nSoftAbort = 0;
39 int nSoftAbortCommit = 0;
40 int nSoftAbortAbort = 0;
41 #endif
42
43 void * A_memcpy (void * dest, const void * src, size_t count) {
44   int off=0;
45   INTPTR *desti=(INTPTR *)dest;
46   INTPTR *srci=(INTPTR *)src;
47
48   //word copy
49   while(count>=sizeof(INTPTR)) {
50     desti[off]=srci[off];
51     off+=1;
52     count-=sizeof(INTPTR);
53   }
54   off*=sizeof(INTPTR);
55   //byte copy
56   while(count>0) {
57     ((char *)dest)[off]=((char *)src)[off];
58     off++;
59     count--;
60   }
61 }
62
63 /* ==================================================
64  * stmStartup
65  * This function starts up the transaction runtime.
66  * ==================================================
67  */
68 int stmStartup() {
69   return 0;
70 }
71
72 /* =================================================
73  * transStart
74  * This function initializes things required in the
75  * transaction start
76  * =================================================
77  */
78 void transStart() {
79   //Transaction start is currently free...commit and aborting is not
80 #ifdef DELAYCOMP
81   c_ptrstack=&ptrstack;
82   c_primstack=&primstack;
83   c_branchstack=&branchstack;
84 #endif
85 }
86
87 /* =======================================================
88  * transCreateObj
89  * This function creates objects in the transaction record
90  * =======================================================
91  */
92 #ifdef STMARRAY
93 objheader_t *transCreateObj(void * ptr, unsigned int size, int bytelength) {
94   char *tmpchar = mygcmalloc(ptr, (sizeof(objheader_t) + size));
95   objheader_t *tmp = (objheader_t *) (tmpchar+bytelength);
96 #else
97 objheader_t *transCreateObj(void * ptr, unsigned int size) {
98   objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size));
99 #endif
100   objheader_t *retval=tmp+1;
101   tmp->lock=SWAP_LOCK_BIAS;
102   tmp->version = 1;
103   //initialize obj lock to the header
104   STATUS(tmp)=NEW;
105   // don't insert into table
106   if (newobjs->offset<MAXOBJLIST) {
107     newobjs->objs[newobjs->offset++]=retval;
108   } else {
109     struct objlist *tmp=malloc(sizeof(struct objlist));
110     tmp->next=newobjs;
111     tmp->objs[0]=retval;
112     tmp->offset=1;
113     newobjs=tmp;
114   }
115   return retval; //want space after object header
116 }
117
118 /* This functions inserts randowm wait delays in the order of msec
119  * Mostly used when transaction commits retry*/
120 void randomdelay(int softaborted) {
121   struct timespec req;
122   struct timeval t;
123
124   gettimeofday(&t,NULL);
125
126   req.tv_sec = 0;
127   req.tv_nsec = (long)((t.tv_usec)%(1<<softaborted))<<1; //1-11 microsec
128   nanosleep(&req, NULL);
129   return;
130 }
131
132 /* =============================================================
133  * transRead
134  * -finds the objects either in main heap
135  * -copies the object into the transaction cache
136  * =============================================================
137  */
138
139 //void *TR(void *x, void * y, void *z) {
140 //  void * inputvalue;                          
141 //  if ((inputvalue=y)==NULL) x=NULL;           
142 //  else {
143 //    chashlistnode_t * cnodetmp=&c_table[(((unsigned INTPTR)inputvalue)&c_mask)>>4]; 
144 //    do { 
145 //      if (cnodetmp->key==inputvalue) {x=cnodetmp->val; break;} 
146 //      cnodetmp=cnodetmp->next; 
147 //      if (cnodetmp==NULL) {if (((struct ___Object___*)inputvalue)->___objstatus___&NEW) {x=inputvalue; break;} else
148 //                           {x=transRead(inputvalue,z); asm volatile ("" : "=m" (c_table),"\=m" (c_mask)); break;}}
149 //    } while(1);
150 //  }
151 //  return x;
152 //}
153
154 //__attribute__ ((pure)) 
155 void *transRead(void * oid, void *gl) {
156   objheader_t *tmp, *objheader;
157   objheader_t *objcopy;
158   int size;
159
160   objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
161 #ifdef STMSTATS
162   header->accessCount++;
163   if(header->riskyflag) {
164     header=needLock(header,gl);
165   }
166 #endif
167 #ifdef STMARRAY
168   int type=TYPE(header);
169   if (type>=NUMCLASSES) {
170     int basesize=((struct ArrayObject *)oid)->___length___*classsize[type];
171     basesize=(basesize+LOWMASK)&HIGHMASK;
172     int metasize=sizeof(int)*2*(basesize>>INDEXSHIFT);
173     size = basesize + sizeof(objheader_t)+metasize+sizeof(struct ArrayObject);
174     char *tmpptr = (char *) objstrAlloc(size);
175     bzero(tmpptr, metasize);//clear out stm data
176     objcopy=(objheader_t *) (tmpptr+metasize);
177     A_memcpy(objcopy, header, sizeof(objheader_t)+sizeof(struct ArrayObject)); //copy the metadata and base array info
178   } else {
179     GETSIZE(size, header);
180     size += sizeof(objheader_t);
181     objcopy = (objheader_t *) objstrAlloc(size);
182     A_memcpy(objcopy, header, size);
183   }
184 #else
185   GETSIZE(size, header);
186   size += sizeof(objheader_t);
187   objcopy = (objheader_t *) objstrAlloc(size);
188   A_memcpy(objcopy, header, size);
189 #endif
190 #ifdef STMSTATS
191   /* keep track of the object's access sequence in a transaction */
192   objheader_t *tmpheader = objcopy;
193   tmpheader->accessCount = ++t_objnumcount;
194 #endif
195   /* Insert into cache's lookup table */
196   STATUS(objcopy)=0;
197   if (((unsigned INTPTR)oid)<((unsigned INTPTR ) curr_heapbase)|| ((unsigned INTPTR)oid) >((unsigned INTPTR) curr_heapptr))
198     printf("ERROR! Bad object address!\n");
199   t_chashInsert(oid, &objcopy[1]);
200   return &objcopy[1];
201 }
202
203 #ifdef STMARRAY
204 //caller needs to mark data as present
205  void arraycopy(struct ArrayObject *oid, int byteindex) {
206    struct ArrayObject * orig=(struct ArrayObject *) oid->___objlocation___;
207    int baseoffset=byteindex&HIGHMASK;
208    unsigned int mainversion;
209    int baseindex=baseoffset>>INDEXSHIFT;
210    GETVERSIONVAL(mainversion, orig, baseindex);
211    SETVERSION(oid, baseindex, mainversion);
212    A_memcpy(((char *)&oid[1])+baseoffset, ((char *)&orig[1])+baseoffset, INDEXLENGTH);
213    if (oid->lowindex>baseoffset)
214      oid->lowindex=baseoffset;
215    if (oid->highindex<baseoffset)
216      oid->highindex=baseoffset;
217  }
218 #endif
219
220 void freenewobjs() {
221   struct objlist *ptr=newobjs;
222   while(ptr->next!=NULL) {
223     struct objlist *tmp=ptr->next;
224     free(ptr);
225     ptr=tmp;
226   }
227   ptr->offset=0;
228   newobjs=ptr;
229 }
230