1 /* ============================================================
3 * - single thread commit on local machine
4 * =============================================================
5 * Copyright (c) 2009, University of California, Irvine, USA.
9 * =============================================================
16 /* Per thread transaction variables */
17 __thread objstr_t *t_cache;
18 __thread objstr_t *t_reserve;
19 __thread struct objlist * newobjs;
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;
36 int numTransCommit = 0;
37 int numTransAbort = 0;
39 int nSoftAbortCommit = 0;
40 int nSoftAbortAbort = 0;
43 void * A_memcpy (void * dest, const void * src, size_t count) {
45 INTPTR *desti=(INTPTR *)dest;
46 INTPTR *srci=(INTPTR *)src;
49 while(count>=sizeof(INTPTR)) {
52 count-=sizeof(INTPTR);
57 ((char *)dest)[off]=((char *)src)[off];
63 /* ==================================================
65 * This function starts up the transaction runtime.
66 * ==================================================
72 /* =================================================
74 * This function initializes things required in the
76 * =================================================
79 //Transaction start is currently free...commit and aborting is not
82 c_primstack=&primstack;
83 c_branchstack=&branchstack;
87 /* =======================================================
89 * This function creates objects in the transaction record
90 * =======================================================
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));
97 objheader_t *transCreateObj(void * ptr, unsigned int size) {
98 objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size));
100 objheader_t *retval=tmp+1;
101 tmp->lock=RW_LOCK_BIAS;
103 //initialize obj lock to the header
105 // don't insert into table
106 if (newobjs->offset<MAXOBJLIST) {
107 newobjs->objs[newobjs->offset++]=retval;
109 struct objlist *tmp=malloc(sizeof(struct objlist));
115 return retval; //want space after object header
118 /* This functions inserts randowm wait delays in the order of msec
119 * Mostly used when transaction commits retry*/
120 void randomdelay(int softaborted) {
124 gettimeofday(&t,NULL);
127 req.tv_nsec = (long)((t.tv_usec)%(1<<softaborted))<<1; //1-11 microsec
128 nanosleep(&req, NULL);
132 /* =============================================================
134 * -finds the objects either in main heap
135 * -copies the object into the transaction cache
136 * =============================================================
139 //void *TR(void *x, void * y, void *z) {
140 // void * inputvalue;
141 // if ((inputvalue=y)==NULL) x=NULL;
143 // chashlistnode_t * cnodetmp=&c_table[(((unsigned INTPTR)inputvalue)&c_mask)>>4];
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;}}
154 //__attribute__ ((pure))
155 void *transRead(void * oid, void *gl) {
156 objheader_t *tmp, *objheader;
157 objheader_t *objcopy;
160 objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
162 header->accessCount++;
163 if(header->riskyflag) {
164 header=needLock(header,gl);
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
178 size += sizeof(objheader_t);
179 objcopy = (objheader_t *) objstrAlloc(size);
180 A_memcpy(objcopy, header, size);
183 GETSIZE(size, header);
184 size += sizeof(objheader_t);
185 objcopy = (objheader_t *) objstrAlloc(size);
186 A_memcpy(objcopy, header, size);
189 /* keep track of the object's access sequence in a transaction */
190 objheader_t *tmpheader = objcopy;
191 tmpheader->accessCount = ++t_objnumcount;
193 /* Insert into cache's lookup table */
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]);
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;
215 struct objlist *ptr=newobjs;
216 while(ptr->next!=NULL) {
217 struct objlist *tmp=ptr->next;