+#ifdef STMSTATS
+#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; \
+ 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; \
+ objtypetraverse[TYPE(header)]=1; \
+ if (getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \
+ softabort=0;
+#define ABORTSTAT4 ObjSeqId = oidrdage[i]; \
+ header->abortCount++; \
+ getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse);
+#else
+#define ABORTSTAT1
+#define ABORTSTAT2
+#define ABORTSTAT3
+#define ABORTSTAT4
+#endif
+
+#ifdef DELAYCOMP
+#define DELAYWRAP(x) x
+#define NUMWRTOTAL numoidwrtotal
+#else
+#define DELAYWRAP(x)
+#define NUMWRTOTAL numoidwrlocked
+#endif
+
+#ifdef STMARRAY
+#define STMARRAYFREE free(oidrdlockedarray);
+#define STMARRAYALLOC oidrdlockedarray=malloc(size);
+#define STMARRAYASSIGN oidrdlockedarray=rdlockedarray;
+
+#define ARRAYDEFINES int numoidrdlockedarray=0; \
+ void * rdlockedarray[200]; \
+ void ** oidrdlockedarray;
+
+#define PROCESSARRAY \
+ int type=((int *)cachedobj)[0]; \
+ if (type>=NUMCLASSES) { \
+ struct ArrayObject *transao=(struct ArrayObject *) cachedobj; \
+ struct ArrayObject *mainao=(struct ArrayObject *) objptr; \
+ int lowoffset=(transao->lowoffset)>>INDEXSHIFT; \
+ int highoffset=(transao->highoffset)>>INDEXSHIFT; \
+ int j; \
+ int addwrobject=0, addrdobject=0; \
+ for(j=lowoffset; j<=highoffset;j++) { \
+ int status; \
+ GETLOCKVAL(status, transao, j); \
+ if (status==STMDIRTY) { \
+ unsigned int * lockptr; \
+ GETLOCKPTR(lockptr, mainao,j); \
+ if (write_trylock(lockptr)) { \
+ unsigned int localversion; \
+ unsigned int remoteversion; \
+ GETVERSIONVAL(localversion, transao, j); \
+ GETVERSIONVAL(remoteversion, mainao, j); \
+ if (localversion == remoteversion) { \
+ addwrobject=1; \
+ } else { \
+ dirwrlocked[numoidwrlocked++] = objptr; \
+ transAbortProcess(oidwrlocked, numoidwrlocked); \
+ freearrays; \
+ if (softabort) \
+ return TRANS_SOFT_ABORT; \
+ else \
+ return TRANS_ABORT; \
+ } \
+ } \
+ } else if (status==STMCLEAN) { \
+ addrdobject=1; \
+ } \
+ } \
+ if (addwrobject) { \
+ dirwrlocked[numoidwrlocked++] = objptr; \
+ } \
+ if (addrdobject) { \
+ rdlockedarray[numrdlockedarray++]=objptr; \
+ } \
+ } else
+
+#define READDARRAYS \
+ for(i=0; i<numoidrdlockedarray; i++) { \
+ objheader_t * transheader=oidrdlockedarray[i]; \
+ struct ArrayObject * transao=(struct ArrayObject *)&transheader[1]; \
+ objheader_t * mainheader=OID(transheader); \
+ struct ArrayObject * mainao=(struct ArrayObject *)&transheader[1]; \
+ int lowoffset=(transao->lowoffset)>>INDEXSHIFT; \
+ int highoffset=(transao->highoffset)>>INDEXSHIFT; \
+ int j; \
+ for(j=lowoffset; j<=highoffset;j++) { \
+ int locallock;GETLOCKVAL(locallock,transao,j); \
+ if (locallock==STMCLEAN) { \
+ /* do read check */ \
+ int mainlock; GETLOCKVAL(mainlock, mainao, j); \
+ if (mainlock>0) { \
+ CFENCE; \
+ unsigned int localversion; \
+ unsigned int remoteversion; \
+ GETVERSIONVAL(localversion, transao, j); \
+ GETVERSIONVAL(remoteversion, mainao, j); \
+ if (localversion != remoteversion) { \
+ transAbortProcess(oidwrlocked, NUMWRTOTAL); \
+ freearrays; \
+ return TRANS_ABORT; \
+ } \
+ } \
+ } \
+ } \
+ }
+#else
+#define ARRAYDEFINES
+#define PROCESSARRAY
+#define READDARRAYS
+#define STMARRAYFREE
+#define STMARRAYALLOC
+#define STMARRAYASSIGN
+#endif
+