#define STATASSIGN
#endif
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+#define ARRAYDELAYWRAP(x) x
+#define ARRAYDELAYWRAP1(x) ,x
+#else
+#define ARRAYDELAYWRAP(x)
+#define ARRAYDELAYWRAP1(x)
+#endif
+
/* ================================================================
* transCommit
* - This function initiates the transaction commit process
* - a final response
* ================================================================
*/
+
#ifdef DELAYCOMP
int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) {
#else
} \
if (t_numelements>=200) { \
free(oidwrlocked); \
+ STMARRAYDELAYFREE; \
}
#else
#define freearrays if (c_numelements>=200) { \
#endif
#ifdef DELAYCOMP
-#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \
- if (t_numelements<200) { \
+#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \
+ if (t_numelements<200) { \
oidwrlocked=(struct garbagelist *) &wrlocked; \
- } else { \
- oidwrlocked=malloc(2*sizeof(INTPTR)+t_numelements*sizeof(void *)); \
- } \
- if (c_numelements<200) { \
- oidrdlocked=rdlocked; \
- oidrdversion=rdversion; \
- STATASSIGN; \
- STMARRAYASSIGN; \
- } else { \
- int size=c_numelements*sizeof(void*); \
- oidrdlocked=malloc(size); \
- oidrdversion=malloc(size); \
- STATALLOC; \
- STMARRAYALLOC; \
- }\
+ STMARRAYDELAYASSIGN; \
+ } else { \
+ oidwrlocked=malloc(2*sizeof(INTPTR)+t_numelements*(sizeof(void *))); \
+ STMARRAYDELAYALLOC; \
+ } \
+ if (c_numelements<200) { \
+ oidrdlocked=rdlocked; \
+ oidrdversion=rdversion; \
+ STATASSIGN; \
+ STMARRAYASSIGN; \
+ } else { \
+ int size=c_numelements*sizeof(void*); \
+ oidrdlocked=malloc(size); \
+ oidrdversion=malloc(size); \
+ STATALLOC; \
+ STMARRAYALLOC; \
+ } \
dirwrlocked=oidwrlocked->array;
#else
-#define allocarrays if (c_numelements<200) { \
- oidrdlocked=rdlocked; \
- oidrdversion=rdversion; \
+#define allocarrays if (c_numelements<200) { \
+ oidrdlocked=rdlocked; \
+ oidrdversion=rdversion; \
oidwrlocked=(struct garbagelist *) &wrlocked; \
STATASSIGN; \
STMARRAYASSIGN; \
- } else { \
- int size=c_numelements*sizeof(void*); \
- oidrdlocked=malloc(size); \
- oidrdversion=malloc(size); \
- oidwrlocked=malloc(size+2*sizeof(INTPTR)); \
- STATALLOC; \
- STMARRAYALLOC; \
- } \
+ } else { \
+ int size=c_numelements*sizeof(void*); \
+ oidrdlocked=malloc(size); \
+ oidrdversion=malloc(size); \
+ oidwrlocked=malloc(size+2*sizeof(INTPTR)); \
+ STATALLOC; \
+ STMARRAYALLOC; \
+ } \
dirwrlocked=oidwrlocked->array;
#endif
#ifdef STMSTATS
-#define ABORTSTAT1 header->abortCount++; \
- ObjSeqId = headeraddr->accessCount; \
+#define ABORTSTAT1 header->abortCount++; \
+ ObjSeqId = headeraddr->accessCount; \
(typesCausingAbort[TYPE(header)]).numabort++; \
(typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \
(typesCausingAbort[TYPE(header)]).numtrans+=1; \
objtypetraverse[TYPE(header)]=1; \
if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \
softabort=0;
-#define ABORTSTAT2 \
- ObjSeqId = oidrdage[i];\
- header->abortCount++; \
- (typesCausingAbort[TYPE(header)]).numabort++; \
- (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \
- (typesCausingAbort[TYPE(header)]).numtrans+=1; \
+#define ABORTSTAT2 \
+ ObjSeqId = oidrdage[i]; \
+ header->abortCount++; \
+ (typesCausingAbort[TYPE(header)]).numabort++; \
+ (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \
+ (typesCausingAbort[TYPE(header)]).numtrans+=1; \
objtypetraverse[TYPE(header)]=1; \
if (getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \
softabort=0;
-#define ABORTSTAT3 \
- header->abortCount++; \
- ObjSeqId = headeraddr->accessCount; \
- (typesCausingAbort[TYPE(header)]).numabort++; \
- (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \
- (typesCausingAbort[TYPE(header)]).numtrans+=1; \
+#define ABORTSTAT3 \
+ header->abortCount++; \
+ ObjSeqId = headeraddr->accessCount; \
+ (typesCausingAbort[TYPE(header)]).numabort++; \
+ (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \
+ (typesCausingAbort[TYPE(header)]).numtrans+=1; \
objtypetraverse[TYPE(header)]=1; \
if (getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \
softabort=0;
-#define ABORTSTAT4 ObjSeqId = oidrdage[i]; \
+#define ABORTSTAT4 ObjSeqId = oidrdage[i]; \
header->abortCount++; \
getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse);
#else
#define STMARRAYFREE free(oidrdlockedarray);
#define STMARRAYALLOC oidrdlockedarray=malloc(size);
#define STMARRAYASSIGN oidrdlockedarray=rdlockedarray;
+#define STMARRAYDELAYFREE free(dirwrindex);
+#define STMARRAYDELAYALLOC dirwrindex=malloc(t_numelements*sizeof(int));
+#define STMARRAYDELAYASSIGN dirwrindex=wrindex;
#define ARRAYDEFINES int numoidrdlockedarray=0; \
void * rdlockedarray[200]; \
write_unlock(lockptr); \
} \
} \
- transAbortProcess(oidwrlocked, numoidwrlocked); \
+ transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); \
freearrays; \
if (softabort) \
return TRANS_SOFT_ABORT; \
if (status==STMDIRTY) { \
unsigned int * lockptr; \
GETLOCKPTR(lockptr, mainao,j); \
- if (write_trylock(lockptr)) { \
+ if (likely(write_trylock(lockptr))) { \
unsigned int localversion; \
unsigned int remoteversion; \
GETVERSIONVAL(localversion, transao, j); \
GETVERSIONVAL(remoteversion, mainao, j); \
- if (localversion == remoteversion) { \
+ if (likely(localversion == remoteversion)) { \
addwrobject=1; \
} else { \
ARRAYABORT; \
GETVERSIONVAL(localversion, transao, j); \
GETVERSIONVAL(remoteversion, mainao, j); \
if (localversion != remoteversion) { \
- transAbortProcess(oidwrlocked, NUMWRTOTAL); \
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \
freearrays; \
return TRANS_ABORT; \
} \
GETVERSIONVAL(remoteversion, mainao, j); \
if (localversion==remoteversion) \
softabort=1; \
- transAbortProcess(oidwrlocked, NUMWRTOTAL); \
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \
freearrays; \
if (softabort) \
return TRANS_SOFT_ABORT; \
#define STMARRAYFREE
#define STMARRAYALLOC
#define STMARRAYASSIGN
+#define STMARRAYDELAYFREE
+#define STMARRAYDELAYALLOC
+#define STMARRAYDELAYASSIGN
#endif
+#ifdef DELAYCOMP
+#ifdef STMARRAY
+#define ARRAYLOCK \
+ int intkey=dc_curr->intkey; \
+ if (intkey!=-1) { \
+ unsigned int *lockptr; \
+ GETLOCKPTR(lockptr, objptr, intkey); \
+ if (likely(write_trylock(lockptr))) { \
+ /*have lock on element */ \
+ dirwrlocked[numoidwrtotal]=objptr; \
+ dirwrindex[numoidwrtotal++]=intkey; \
+ } else { \
+ unsigned int lockval; \
+ GETLOCKVAL(lockval, valptr, intkey); \
+ if (lockval!=STMDIRTY) { \
+ /*have to abort to avoid deadlock*/ \
+ transAbortProcess(oidwrlocked, numoidwrtotal, dirwrindex, numoidwrlocked); \
+ ABORTSTAT1; \
+ freearrays; \
+ if (softabort) \
+ return TRANS_SOFT_ABORT; \
+ else \
+ return TRANS_ABORT; \
+ } \
+ } \
+ } else
+#else
+#define ARRAYLOCK
+#endif
+#define ACCESSLOCKS \
+ unsigned int numoidwrtotal=numoidwrlocked; \
+ dchashlistnode_t *dc_curr = dc_c_list; \
+ /* Inner loop to traverse the linked list of the cache lookupTable */ \
+ while(likely(dc_curr != NULL)) { \
+ /*if the first bin in hash table is empty */ \
+ void *valptr=dc_curr->val; \
+ objheader_t * headeraddr=&((objheader_t *) valptr)[-1]; \
+ void *objptr=dc_curr->key; \
+ objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t)); \
+ ARRAYLOCK \
+ if(likely(write_trylock(&header->lock))) { /*can aquire write lock*/ \
+ ARRAYDELAYWRAP(dirwrindex[numoidwrtotal]=-1;) \
+ dirwrlocked[numoidwrtotal++] = objptr; \
+ } else { \
+ /* maybe we already have lock*/ \
+ chashlistnode_t *node = &c_table[(((unsigned INTPTR)objptr) & c_mask)>>4]; \
+ \
+ do { \
+ if(node->key == objptr) { \
+ objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; \
+ if(STATUS(headeraddr) & DIRTY) { \
+ goto nextloop; \
+ } else \
+ break; \
+ } \
+ node = node->next; \
+ } while(node != NULL); \
+ \
+ /*have to abort to avoid deadlock */ \
+ transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \
+ ABORTSTAT1; \
+ freearrays; \
+ if (softabort) \
+ return TRANS_SOFT_ABORT; \
+ else \
+ return TRANS_ABORT; \
+ } \
+ nextloop: \
+ dc_curr = dc_curr->lnext; \
+ }
+#else
+#define ACCESSLOCKS
+#endif
+
+
+
+
/* ==================================================
* traverseCache
* - goes through the transaction cache and
*/
#ifdef DELAYCOMP
- int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) {
+int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) {
#else
- int traverseCache() {
+int traverseCache() {
#endif
/* Create info to keep track of objects that can be locked */
int numoidrdlocked=0;
STMWRAP(int rdage[200];int * oidrdage;int ObjSeqId;int objtypetraverse[TOTALNUMCLASSANDARRAY];);
struct garbagelist * oidwrlocked;
void ** dirwrlocked;
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+ int wrindex[200];
+ int * dirwrindex;
+#endif
allocarrays;
STMWRAP(for(i=0; i<TOTALNUMCLASSANDARRAY; i++) objtypetraverse[i] = 0;);
if(STATUS(headeraddr) & DIRTY) {
/* Read from the main heap and compare versions */
- if(write_trylock(&header->lock)) { //can aquire write lock
- if (version == header->version) { /* versions match */
+ if(likely(write_trylock(&header->lock))) { //can aquire write lock
+ if (likely(version == header->version)) { /* versions match */
/* Keep track of objects locked */
dirwrlocked[numoidwrlocked++] = objptr;
} else {
dirwrlocked[numoidwrlocked++] = objptr;
- transAbortProcess(oidwrlocked, numoidwrlocked);
+ transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT1;
freearrays;
if (softabort)
/* versions match */
softabort=1;
}
- transAbortProcess(oidwrlocked, numoidwrlocked);
+ transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT1;
freearrays;
if (softabort)
}
} //end of for
-#ifdef DELAYCOMP
- //acquire access set locks
- unsigned int numoidwrtotal=numoidwrlocked;
-
- dchashlistnode_t *dc_curr = dc_c_list;
- /* Inner loop to traverse the linked list of the cache lookupTable */
- while(likely(dc_curr != NULL)) {
- //if the first bin in hash table is empty
- objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1];
- void *objptr=dc_curr->key;
- objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t));
- if(write_trylock(&header->lock)) { //can aquire write lock
- dirwrlocked[numoidwrtotal++] = objptr;
- } else {
- //maybe we already have lock
- void * key=dc_curr->key;
- chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
-
- do {
- if(node->key == key) {
- objheader_t * headeraddr=&((objheader_t *) node->val)[-1];
- if(STATUS(headeraddr) & DIRTY) {
- goto nextloop;
- } else
- break;
- }
- node = node->next;
- } while(node != NULL);
-
- //have to abort to avoid deadlock
- transAbortProcess(oidwrlocked, numoidwrtotal);
- ABORTSTAT1;
- freearrays;
- if (softabort)
- return TRANS_SOFT_ABORT;
- else
- return TRANS_ABORT;
- }
- nextloop:
- dc_curr = dc_curr->lnext;
- }
-#endif
+ ACCESSLOCKS;
//THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)*****
-
READARRAYS;
for(i=0; i<numoidrdlocked; i++) {
if(header->lock>0) { //not write locked
CFENCE;
if(version != header->version) { /* versions do not match */
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT2;
freearrays;
return TRANS_ABORT;
//couldn't get lock because we already have it
//check if it is the right version number
if (version!=header->version) {
- transAbortProcess(oidwrlocked, numoidwrtotal);
+ transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT2;
freearrays;
return TRANS_ABORT;
if(version == header->version) {
softabort=1;
}
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT2;
freearrays;
if (softabort)
if(header->lock>0) { //object is not locked
if (version!=header->version) {
//have to abort
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
STMWRAP((typesCausingAbort[TYPE(header)])++;);
freearrays;
if (softabort)
}
}
//have to abort to avoid deadlock
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
STMWRAP((typesCausingAbort[TYPE(header)])++;);
freearrays;
if (softabort)
/* Decide the final response */
#ifdef DELAYCOMP
- transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params);
+ transCommitProcess(oidwrlocked ARRAYDELAYWRAP1(dirwrindex), numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params);
#else
transCommitProcess(oidwrlocked, numoidwrlocked);
#endif
ARRAYDEFINES;
struct garbagelist * oidwrlocked;
void ** dirwrlocked;
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+ int wrindex[200];
+ int * dirwrindex;
+#endif
allocarrays;
STMWRAP(for(i=0; i<TOTALNUMCLASSANDARRAY; i++) objtypetraverse[i] = 0;);
dirwrlocked[numoidwrlocked++] = objptr;
} else {
dirwrlocked[numoidwrlocked++] = objptr;
- transAbortProcess(oidwrlocked, numoidwrlocked);
+ transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT3;
freearrays;
return TRANS_ABORT;
/* versions match */
softabort=1;
}
- transAbortProcess(oidwrlocked, numoidwrlocked);
+ transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT3;
freearrays;
if (softabort)
curr = curr->lnext;
}
-#ifdef DELAYCOMP
- //acquire other locks
- unsigned int numoidwrtotal=numoidwrlocked;
- dchashlistnode_t *dc_curr = dc_c_list;
- /* Inner loop to traverse the linked list of the cache lookupTable */
- while(likely(dc_curr != NULL)) {
- //if the first bin in hash table is empty
- objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1];
- void *objptr=dc_curr->key;
- objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t));
- if(write_trylock(&header->lock)) { //can aquire write lock
- dirwrlocked[numoidwrtotal++] = objptr;
- } else {
- //maybe we already have lock
- void * key=dc_curr->key;
- chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
-
- do {
- if(node->key == key) {
- objheader_t * headeraddr=&((objheader_t *) node->val)[-1];
- if(STATUS(headeraddr) & DIRTY) {
- goto nextloop;
- }
- }
- node = node->next;
- } while(node != NULL);
-
- //have to abort to avoid deadlock
- transAbortProcess(oidwrlocked, numoidwrtotal);
- ABORTSTAT3;
- freearrays;
- if (softabort)
- return TRANS_SOFT_ABORT;
- else
- return TRANS_ABORT;
- }
- nextloop:
- dc_curr = dc_curr->lnext;
- }
-#endif
+ ACCESSLOCKS;
//THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)*****
READARRAYS;
if(header->lock>0) {
CFENCE;
if(version != header->version) {
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT2;
freearrays;
return TRANS_ABORT;
//couldn't get lock because we already have it
//check if it is the right version number
if (version!=header->version) {
- transAbortProcess(oidwrlocked, numoidwrtotal);
+ transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT4;
freearrays;
return TRANS_ABORT;
if(version == header->version) {
softabort=1;
}
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
ABORTSTAT2;
freearrays;
if (softabort)
if(header->lock>0) { //object is not locked
if (version!=header->version) {
//have to abort
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
STMWRAP((typesCausingAbort[TYPE(header)])++;);
freearrays;
if (softabort)
}
}
//have to abort to avoid deadlock
- transAbortProcess(oidwrlocked, NUMWRTOTAL);
+ transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
STMWRAP((typesCausingAbort[TYPE(header)])++;);
freearrays;
if (softabort)
/* Decide the final response */
#ifdef DELAYCOMP
- transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params);
+ transCommitProcess(oidwrlocked ARRAYDELAYWRAP1(dirwrindex), numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params);
#else
transCommitProcess(oidwrlocked, numoidwrlocked);
#endif
*/
int logflag=1;
-
+
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrtotal, int * dirwrindex, int numoidwrlocked) {
+#else
void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) {
+#endif
int i;
objheader_t *header;
/* Release read locks */
#endif
write_unlock(&header->lock);
}
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+ //release access locks
+ for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) {
+ struct ___Object___ * dst=dirwrlocked[i];
+ header = &((objheader_t *)dst)[-1];
+ int wrindex=dirwrindex[i];
+ if (wrindex==-1) {
+ //normal object
+ header->version++;
+ write_unlock(&header->lock);
+ } else {
+ //array element
+ unsigned int *intptr;
+ GETVERSIONPTR(intptr, ((struct ArrayObject *)dst), wrindex);
+ (*intptr)++;
+ GETLOCKPTR(intptr, ((struct ArrayObject *)dst), wrindex);
+ write_unlock(intptr);
+ }
+ }
+#endif
#ifdef STMSTATS
/* clear trec and then release objects locked */
struct objlist *ptr=lockedobjs;
* =================================
*/
#ifdef DELAYCOMP
- void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) {
+void transCommitProcess(struct garbagelist * oidwrlocked ARRAYDELAYWRAP1(int * dirwrindex), int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) {
#else
void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) {
#endif
#endif
/* Release write locks */
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+ for(i=numoidwrlocked-1; i>=0; i--) {
+#else
for(i=NUMWRTOTAL-1; i>=0; i--) {
+#endif
struct ___Object___ * dst=dirwrlocked[i];
header = &((objheader_t *)dst)[-1];
#ifdef STMARRAY
write_unlock(&header->lock);
}
}
-
+#if defined(STMARRAY)&&defined(DELAYCOMP)
+ //release access locks
+ for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) {
+ struct ___Object___ * dst=dirwrlocked[i];
+ header = &((objheader_t *)dst)[-1];
+ int wrindex=dirwrindex[i];
+ if (wrindex==-1) {
+ //normal object
+ header->version++;
+ write_unlock(&header->lock);
+ } else {
+ //array element
+ unsigned int *intptr;
+ GETVERSIONPTR(intptr, ((struct ArrayObject *)dst), wrindex);
+ (*intptr)++;
+ GETLOCKPTR(intptr, ((struct ArrayObject *)dst), wrindex);
+ write_unlock(intptr);
+ }
+ }
+#endif
#ifdef STMSTATS
/* clear trec and then release objects locked */
ptr=lockedobjs;