objheader_t *transCreateObj(void * ptr, unsigned int size) {
objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size));
objheader_t *retval=&tmp[1];
+ initdsmlocks(&tmp->lock);
tmp->version = 1;
t_chashInsert((unsigned int) retval, retval);
-
return retval; //want space after object header
}
t = time(NULL);
req.tv_sec = 0;
- req.tv_nsec = (long)(1000 + (t%10000)); //1-11 microsec
+ req.tv_nsec = (long)(t%100); //1-11 microsec
nanosleep(&req, NULL);
return;
}
* -copies the object into the transaction cache
* =============================================================
*/
-__attribute__((pure)) objheader_t *transRead(unsigned int oid) {
+__attribute__((pure)) void *transRead(void * oid) {
unsigned int machinenumber;
objheader_t *tmp, *objheader;
objheader_t *objcopy;
/* Read from the main heap */
objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
- if(read_trylock(STATUSPTR(header))) { //Can further acquire read locks
+ if(read_trylock(&header->lock)) { //Can further acquire read locks
GETSIZE(size, header);
size += sizeof(objheader_t);
objcopy = (objheader_t *) objstrAlloc(&t_cache, size);
memcpy(objcopy, header, size);
/* Insert into cache's lookup table */
STATUS(objcopy)=0;
- t_chashInsert(OID(header), objcopy);
+ t_chashInsert((unsigned int)oid, &objcopy[1]);
+ read_unlock(&header->lock);
return &objcopy[1];
}
- read_unlock(STATUSPTR(header));
}
/* ================================================================
* ================================================================
*/
int transCommit() {
- int finalResponse;
- char treplyretry; /* keeps track of the common response that needs to be sent */
-
do {
- treplyretry = 0;
/* Look through all the objects in the transaction hash table */
- finalResponse = traverseCache(&treplyretry);
+ int finalResponse = traverseCache();
if(finalResponse == TRANS_ABORT) {
- break;
+ objstrDelete(t_cache);
+ t_chashDelete();
+ return TRANS_ABORT;
}
if(finalResponse == TRANS_COMMIT) {
- break;
+ objstrDelete(t_cache);
+ t_chashDelete();
+ return 0;
}
/* wait a random amount of time before retrying to commit transaction*/
- if(treplyretry && (finalResponse == TRANS_SOFT_ABORT)) {
+ if(finalResponse == TRANS_SOFT_ABORT) {
randomdelay();
- }
- if(finalResponse != TRANS_ABORT && finalResponse != TRANS_COMMIT && finalResponse != TRANS_SOFT_ABORT) {
+ } else {
printf("Error: in %s() Unknown outcome", __func__);
exit(-1);
}
- /* Retry trans commit procedure during soft_abort case */
- } while (treplyretry);
-
- if(finalResponse == TRANS_ABORT) {
- /* Free Resources */
- objstrDelete(t_cache);
- t_chashDelete();
- return TRANS_ABORT;
- } else if(finalResponse == TRANS_COMMIT) {
- /* Free Resources */
- objstrDelete(t_cache);
- t_chashDelete();
- return 0;
- } else {
- //TODO Add other cases
- printf("Error: in %s() THIS SHOULD NOT HAPPEN.....EXIT PROGRAM\n", __func__);
- exit(-1);
- }
- return 0;
+ } while (1);
}
/* ==================================================
* - decides if a transaction should commit or abort
* ==================================================
*/
-int traverseCache(char *treplyretry) {
- /* Create info for newly creately objects */
- int numcreated=0;
- unsigned int oidcreated[c_numelements];
+int traverseCache() {
/* Create info to keep track of objects that can be locked */
int numoidrdlocked=0;
int numoidwrlocked=0;
unsigned int oidrdlocked[c_numelements];
unsigned int oidwrlocked[c_numelements];
- /* Counters to decide final response of this transaction */
- int vmatch_lock;
- int vmatch_nolock;
- int vnomatch;
- int numoidread;
- int numoidmod;
- int response;
-
+ int softabort=0;
int i;
chashlistnode_t *ptr = c_table;
/* Represents number of bins in the chash table */
//if the first bin in hash table is empty
if(curr->key == 0)
break;
- objheader_t * headeraddr=(objheader_t *) curr->val;
- response = decideResponse(headeraddr, oidcreated, &numcreated, oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked,
- &vmatch_lock, &vmatch_nolock, &vnomatch, &numoidmod, &numoidread);
+ objheader_t * headeraddr=&((objheader_t *) curr->val)[-1];
+ int response = decideResponse(headeraddr, oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
+
if(response == TRANS_ABORT) {
- *treplyretry = 0;
transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
return TRANS_ABORT;
+ } else if (response == TRANS_SOFT_ABORT) {
+ softabort=1;
}
curr = curr->next;
}
} //end of for
/* Decide the final response */
- if(vmatch_nolock == (numoidread + numoidmod)) {
- *treplyretry = 0;
- transCommitProcess(oidcreated, &numcreated, oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
- response = TRANS_COMMIT;
- }
- if(vmatch_lock > 0 && vnomatch == 0) {
- *treplyretry = 1;
- response = TRANS_SOFT_ABORT;
+ if (softabort) {
+ return TRANS_SOFT_ABORT;
+ } else {
+ transCommitProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
+ return TRANS_COMMIT;
}
- return response;
}
/* ===========================================================================
* - updates the oids locked and oids newly created
* ===========================================================================
*/
-int decideResponse(objheader_t *headeraddr, unsigned int *oidcreated, int *numcreated, unsigned int* oidrdlocked, int *numoidrdlocked,
- unsigned int*oidwrlocked, int *numoidwrlocked, int *vmatch_lock, int *vmatch_nolock, int *vnomatch, int *numoidmod, int *numoidread) {
- unsigned short version = headeraddr->version;
+int decideResponse(objheader_t *headeraddr, unsigned int* oidrdlocked, int *numoidrdlocked, unsigned int*oidwrlocked, int *numoidwrlocked) {
+ unsigned int version = headeraddr->version;
unsigned int oid = OID(headeraddr);
+ int nolock = 0;
+
if(STATUS(headeraddr) & NEW) {
- oidcreated[(*numcreated)++] = OID(headeraddr);
} else if(STATUS(headeraddr) & DIRTY) {
- (*numoidmod)++;
/* Read from the main heap and compare versions */
- objheader_t *header = (objheader_t *)(((char *)(&oid)) - sizeof(objheader_t));
- if(write_trylock(STATUSPTR(header))) { //can aquire write lock
+ objheader_t *header = (objheader_t *)(((char *)(oid)) - sizeof(objheader_t));
+ if(write_trylock(&header->lock)) { //can aquire write lock
if (version == header->version) {/* versions match */
/* Keep track of objects locked */
- (*vmatch_nolock)++;
oidwrlocked[(*numoidwrlocked)++] = OID(header);
} else {
- (*vnomatch)++;
oidwrlocked[(*numoidwrlocked)++] = OID(header);
return TRANS_ABORT;
}
} else { /* cannot aquire lock */
if(version == header->version) /* versions match */
- (*vmatch_lock)++;
+ nolock=1;
else {
- (*vnomatch)++;
return TRANS_ABORT;
}
}
} else {
- (*numoidread)++;
/* Read from the main heap and compare versions */
- objheader_t *header = (objheader_t *)(((char *)(&oid)) - sizeof(objheader_t));
- if(read_trylock(STATUSPTR(header))) { //can further aquire read locks
+ objheader_t *header = (objheader_t *)(((char *)(oid)) - sizeof(objheader_t));
+ if(read_trylock(&header->lock)) { //can further aquire read locks
if(version == header->version) {/* versions match */
- (*vmatch_nolock)++;
oidrdlocked[(*numoidrdlocked)++] = OID(header);
} else {
- (*vnomatch)++;
oidrdlocked[(*numoidrdlocked)++] = OID(header);
return TRANS_ABORT;
}
} else { /* cannot aquire lock */
if(version == header->version)
- (*vmatch_lock)++;
+ nolock=1;
else {
- (*vnomatch)++;
return TRANS_ABORT;
}
}
}
- return 0;
+ if (nolock)
+ return TRANS_SOFT_ABORT;
+ else
+ return TRANS_COMMIT;
}
/* ==================================
/* Release read locks */
for(i=0; i< *numoidrdlocked; i++) {
/* Read from the main heap */
- if((header = (objheader_t *)(((char *)(&oidrdlocked[i])) - sizeof(objheader_t))) == NULL) {
- printf("Error: %s() main heap returned NULL at %s, %d\n", __func__, __FILE__, __LINE__);
- return 1;
- }
- read_unlock(STATUSPTR(header));
+ header = (objheader_t *)(((char *)(oidrdlocked[i])) - sizeof(objheader_t));
+ read_unlock(&header->lock);
}
/* Release write locks */
for(i=0; i< *numoidwrlocked; i++) {
/* Read from the main heap */
- if((header = (objheader_t *)(((char *)(&oidwrlocked[i])) - sizeof(objheader_t))) == NULL) {
- printf("Error: %s() main heap returned NULL at %s, %d\n", __func__, __FILE__, __LINE__);
- return 1;
- }
- write_unlock(STATUSPTR(header));
+ header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t));
+ write_unlock(&header->lock);
}
}
*
* =================================
*/
-int transCommitProcess(unsigned int *oidcreated, int *numoidcreated, unsigned int *oidrdlocked, int *numoidrdlocked,
+int transCommitProcess(unsigned int *oidrdlocked, int *numoidrdlocked,
unsigned int *oidwrlocked, int *numoidwrlocked) {
- objheader_t *header, *tcptr;
+ objheader_t *header;
void *ptrcreate;
-
int i;
- /* If object is newly created inside transaction then commit it */
- for (i = 0; i < *numoidcreated; i++) {
- if ((header = ((objheader_t *) t_chashSearch(oidcreated[i]))) == NULL) {
- printf("Error: %s() chashSearch returned NULL for oid = %x at %s, %d\n", __func__, oidcreated[i], __FILE__, __LINE__);
- return 1;
- }
- int tmpsize;
- GETSIZE(tmpsize, header);
- tmpsize += sizeof(objheader_t);
- /* FIXME Is this correct? */
-#ifdef PRECISE_GC
- ptrcreate = mygcmalloc((struct garbagelist *)header, tmpsize);
-#else
- ptrcreate = FREEMALLOC(tmpsize);
-#endif
- /* Initialize read and write locks */
- initdsmlocks(STATUSPTR(header));
- memcpy(ptrcreate, header, tmpsize);
- }
/* Copy from transaction cache -> main object store */
for (i = 0; i < *numoidwrlocked; i++) {
/* Read from the main heap */
- if((header = (objheader_t *)(((char *)(&oidwrlocked[i])) - sizeof(objheader_t))) == NULL) {
- printf("Error: %s() main heap returns NULL at %s, %d\n", __func__, __FILE__, __LINE__);
- return 1;
- }
- if ((tcptr = ((objheader_t *) t_chashSearch(oidwrlocked[i]))) == NULL) {
- printf("Error: %s() chashSearch returned NULL at %s, %d\n", __func__, __FILE__, __LINE__);
- return 1;
- }
+ header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t));
int tmpsize;
GETSIZE(tmpsize, header);
- char *tmptcptr = (char *) tcptr;
- {
- struct ___Object___ *dst=(struct ___Object___*)((char*)header+sizeof(objheader_t));
- struct ___Object___ *src=(struct ___Object___*)((char*)tmptcptr+sizeof(objheader_t));
- dst->___cachedCode___=src->___cachedCode___;
- dst->___cachedHash___=src->___cachedHash___;
-
- memcpy(&dst[1], &src[1], tmpsize-sizeof(struct ___Object___));
- }
-
+ struct ___Object___ *dst=(struct ___Object___*)oidwrlocked[i];
+ struct ___Object___ *src=t_chashSearch(oidwrlocked[i]);
+ dst->___cachedCode___=src->___cachedCode___;
+ dst->___cachedHash___=src->___cachedHash___;
+ memcpy(&dst[1], &src[1], tmpsize-sizeof(struct ___Object___));
header->version += 1;
}
/* Release read locks */
for(i=0; i< *numoidrdlocked; i++) {
/* Read from the main heap */
- header = (objheader_t *)(((char *)(&oidrdlocked[i])) - sizeof(objheader_t));
- read_unlock(STATUSPTR(header));
+ header = (objheader_t *)(((char *)(oidrdlocked[i])) - sizeof(objheader_t));
+ read_unlock(&header->lock);
}
/* Release write locks */
for(i=0; i< *numoidwrlocked; i++) {
- header = (objheader_t *)(((char *)(&oidwrlocked[i])) - sizeof(objheader_t));
- write_unlock(STATUSPTR(header));
+ header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t));
+ write_unlock(&header->lock);
}
return 0;