changes
[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 objheader_t *transCreateObj(void * ptr, unsigned int size) {
93   objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size));
94   objheader_t *retval=&tmp[1];
95   tmp->lock=RW_LOCK_BIAS;
96   tmp->version = 1;
97   //initialize obj lock to the header
98   STATUS(tmp)=NEW;
99   // don't insert into table
100   if (newobjs->offset<MAXOBJLIST) {
101     newobjs->objs[newobjs->offset++]=retval;
102   } else {
103     struct objlist *tmp=malloc(sizeof(struct objlist));
104     tmp->next=newobjs;
105     tmp->objs[0]=retval;
106     tmp->offset=1;
107     newobjs=tmp;
108   }
109   return retval; //want space after object header
110 }
111
112 /* This functions inserts randowm wait delays in the order of msec
113  * Mostly used when transaction commits retry*/
114 void randomdelay(int softaborted) {
115   struct timespec req;
116   struct timeval t;
117
118   gettimeofday(&t,NULL);
119
120   req.tv_sec = 0;
121   req.tv_nsec = (long)((t.tv_usec)%(1<<softaborted))<<1; //1-11 microsec
122   nanosleep(&req, NULL);
123   return;
124 }
125
126 /* =============================================================
127  * transRead
128  * -finds the objects either in main heap
129  * -copies the object into the transaction cache
130  * =============================================================
131  */
132
133 //void *TR(void *x, void * y, void *z) {
134 //  void * inputvalue;                          
135 //  if ((inputvalue=y)==NULL) x=NULL;           
136 //  else {
137 //    chashlistnode_t * cnodetmp=&c_table[(((unsigned INTPTR)inputvalue)&c_mask)>>4]; 
138 //    do { 
139 //      if (cnodetmp->key==inputvalue) {x=cnodetmp->val; break;} 
140 //      cnodetmp=cnodetmp->next; 
141 //      if (cnodetmp==NULL) {if (((struct ___Object___*)inputvalue)->___objstatus___&NEW) {x=inputvalue; break;} else
142 //                           {x=transRead(inputvalue,z); asm volatile ("" : "=m" (c_table),"\=m" (c_mask)); break;}}
143 //    } while(1);
144 //  }
145 //  return x;
146 //}
147
148 //__attribute__ ((pure)) 
149 void *transRead(void * oid, void *gl) {
150   objheader_t *tmp, *objheader;
151   objheader_t *objcopy;
152   int size;
153
154   /* Read from the main heap */
155   //No lock for now
156   objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
157   GETSIZE(size, header);
158   size += sizeof(objheader_t);
159   objcopy = (objheader_t *) objstrAlloc(size);
160 #ifdef STMSTATS
161   header->accessCount++;
162   if(header->riskyflag) {
163     header=needLock(header,gl);
164   }
165 #endif
166   A_memcpy(objcopy, header, size);
167 #ifdef STMSTATS
168   /* keep track of the object's access sequence in a transaction */
169   objheader_t *tmpheader = objcopy;
170   tmpheader->accessCount = ++t_objnumcount;
171 #endif
172
173   /* Insert into cache's lookup table */
174   STATUS(objcopy)=0;
175   if (((unsigned INTPTR)oid)<((unsigned INTPTR ) curr_heapbase)|| ((unsigned INTPTR)oid) >((unsigned INTPTR) curr_heapptr))
176     printf("ERROR! Bad object address!\n");
177   t_chashInsert(oid, &objcopy[1]);
178   return &objcopy[1];
179 }
180
181 void freenewobjs() {
182   struct objlist *ptr=newobjs;
183   while(ptr->next!=NULL) {
184     struct objlist *tmp=ptr->next;
185     free(ptr);
186     ptr=tmp;
187   }
188   ptr->offset=0;
189   newobjs=ptr;
190 }
191