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 char *tmpchar = mygcmalloc(ptr, (sizeof(objheader_t) + size));
95 objheader_t *tmp = (objheader_t *) (tmpchar+bytelength);
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 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
179 GETSIZE(size, header);
180 size += sizeof(objheader_t);
181 objcopy = (objheader_t *) objstrAlloc(size);
182 A_memcpy(objcopy, header, size);
185 GETSIZE(size, header);
186 size += sizeof(objheader_t);
187 objcopy = (objheader_t *) objstrAlloc(size);
188 A_memcpy(objcopy, header, size);
191 /* keep track of the object's access sequence in a transaction */
192 objheader_t *tmpheader = objcopy;
193 tmpheader->accessCount = ++t_objnumcount;
195 /* Insert into cache's lookup table */
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]);
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;
221 struct objlist *ptr=newobjs;
222 while(ptr->next!=NULL) {
223 struct objlist *tmp=ptr->next;