13f49a798901f40f43cf21294c345537fa70b637
[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   int *tmpint = mygcmalloc(ptr, (sizeof(objheader_t) + size));
95   objheader_t *tmp = (objheader_t *) (tmpint+(bytelength>>DBLINDEXSHIFT));
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=RW_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   GETSIZE(size, header);
169   int type=TYPE(header);
170   if (type>=NUMCLASSES) {
171     int metasize=sizeof(int)*((((struct ArrayObject *)oid)->___length___*classsize[type])>>DBLINDEXSHIFT);
172     size += sizeof(objheader_t)+metasize;
173     char *tmpptr = (char *) objstrAlloc(size);
174     bzero(objcopy, metasize);//clear out stm data
175     objcopy=tmpptr+metasize;
176     A_memcpy(objcopy, header, sizeof(objheader_t)+sizeof(struct ArrayObject)); //copy the metadata and base array info
177   } else {
178     size += sizeof(objheader_t);
179     objcopy = (objheader_t *) objstrAlloc(size);
180     A_memcpy(objcopy, header, size);
181   }
182 #else
183   GETSIZE(size, header);
184   size += sizeof(objheader_t);
185   objcopy = (objheader_t *) objstrAlloc(size);
186   A_memcpy(objcopy, header, size);
187 #endif
188 #ifdef STMSTATS
189   /* keep track of the object's access sequence in a transaction */
190   objheader_t *tmpheader = objcopy;
191   tmpheader->accessCount = ++t_objnumcount;
192 #endif
193   /* Insert into cache's lookup table */
194   STATUS(objcopy)=0;
195   if (((unsigned INTPTR)oid)<((unsigned INTPTR ) curr_heapbase)|| ((unsigned INTPTR)oid) >((unsigned INTPTR) curr_heapptr))
196     printf("ERROR! Bad object address!\n");
197   t_chashInsert(oid, &objcopy[1]);
198   return &objcopy[1];
199 }
200
201 #ifdef STMARRAY
202 //caller needs to mark data as present
203  void arraycopy(struct ArrayObject *oid, int byteindex) {
204    struct ArrayObject * orig=oid->___objlocation___;
205    int baseoffset=byteindex&HIGHMASK;
206    A_memcpy(((char *)&oid[1])+baseoffset, ((char *)&orig[1])+baseoffset, INDEXLENGTH);
207    if (oid->lowoffset>baseoffset)
208      oid->lowoffset=baseoffset;
209    if (oid->highoffset<baseoffset)
210      oid->highoffset=baseoffset;
211  }
212 #endif
213
214 void freenewobjs() {
215   struct objlist *ptr=newobjs;
216   while(ptr->next!=NULL) {
217     struct objlist *tmp=ptr->next;
218     free(ptr);
219     ptr=tmp;
220   }
221   ptr->offset=0;
222   newobjs=ptr;
223 }
224