#define STMGETARRAY(dst, array, index, type) { \
int byteindex=index*sizeof(type); \
int * lengthoff=&array->___length___; \
- if (array!=array->___objlocation___) { \
+ if (((char *)array)!=((char *)array->___objlocation___)) { \
if(!(array->___objstatus___&NEW)) { \
int *status; \
GETLOCKPTR(status, array, byteindex>>INDEXSHIFT); \
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
#endif
#ifdef SANDBOX
abortenabled=1;
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
#endif
return 0;
}
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
#endif
return TRANS_ABORT;
}
if (addrdobject) { \
oidrdlockedarray[numoidrdlockedarray++]=objptr; \
} \
- } else
+ } else
#define READARRAYS \
for(i=0; i<numoidrdlockedarray; i++) { \
//acquire access set locks
unsigned int numoidwrtotal=numoidwrlocked;
- chashlistnode_t *dc_curr = dc_c_list;
+ 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
#ifdef DELAYCOMP
//check to see if it is in the delaycomp table
{
- chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+ dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
do {
if(node->key == key)
goto nextloopread;
#ifdef DELAYCOMP
//acquire other locks
unsigned int numoidwrtotal=numoidwrlocked;
- chashlistnode_t *dc_curr = dc_c_list;
+ 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
#ifdef DELAYCOMP
//check to see if it is in the delaycomp table
{
- chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+ dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
do {
if(node->key == key)
goto nextloopread;
#ifdef DELAYCOMP
// call commit method
- ptrstack.count=0;
+ ptrstack.maxcount=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.maxcount=0;
+#endif
//splice oidwrlocked in
oidwrlocked->size=numoidwrtotal;
oidwrlocked->next=params;
#define MAXPOINTERS 1024*1024*1
#define MAXVALUES 1024*1024*2
#define MAXBRANCHES 1024*1024*4
+#define MAXARRAY 1024*1024
struct pointerlist {
int count;
void * prev;
- void * array[MAXPOINTERS+1024];
+ void * array[MAXPOINTERS];
+ int maxcount;
+ void * buffer[1024];
};
struct primitivelist {
extern __thread struct pointerlist ptrstack;
extern __thread struct primitivelist primstack;
extern __thread struct branchlist branchstack;
+#ifdef STMARRAY
+struct arraylist {
+ int count;
+ void * prev;
+ void *array[MAXARRAY];
+ int maxcount;
+ int index[MAXARRAY+1024];
+};
+
+extern __thread struct arraylist arraystack;
+#endif
+
+//Arrays
+
+#define RESTOREARRAY(x,z) {x=arraystack.array[arraystack.maxcount];z=arraystack.index[arraystack.maxcount++];}
+
+#define STOREARRAY(x,z) {void * y=COMPOID(x); arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; dc_t_chashInsertOnce(y,y,z);}
+
+#define STOREARRAYNOLOCK(x,z) {void * y=COMPOID(x); arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z;}
+
+#define STOREARRAYNOTRANS(x,z) {void * y=x; arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; dc_t_chashInsertOnce(y,y,z);}
+
+#define STOREARRAYNOLOCKNOTRANS(x,z) {void * y=x; arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; }
//Pointers
-#define RESTOREPTR(x) x=ptrstack.array[ptrstack.count++];
+#define RESTOREPTR(x) x=ptrstack.array[ptrstack.maxcount++];
#define STOREPTR(x) {void * y=COMPOID(x); ptrstack.array[ptrstack.count++]=y; dc_t_chashInsertOnce(y,y);}
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
#endif
_longjmp(aborttrans, 1);
}
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
#endif
_longjmp(aborttrans, 1);
}
__thread struct pointerlist ptrstack;
__thread struct primitivelist primstack;
__thread struct branchlist branchstack;
-struct pointerlist *c_ptrstack;
-struct primitivelist *c_primstack;
-struct branchlist *c_branchstack;
+#ifdef STMARRAY
+__thread struct arraylist arraystack;
+#endif
#endif
#ifdef TRANSSTATS
*/
void transStart() {
//Transaction start is currently free...commit and aborting is not
-#ifdef DELAYCOMP
- c_ptrstack=&ptrstack;
- c_primstack=&primstack;
- c_branchstack=&branchstack;
-#endif
}
/* =======================================================
}
-static inline void atomic_add(int i, unsigned int *v) {
+static inline void atomic_add(int i, volatile unsigned int *v) {
__asm__ __volatile__ (LOCK_PREFIX "addl %1,%0"
: "+m" (*v)
: "ir" (i));
}
-static inline void read_unlock(volatile unsigned int *rw) {
+static inline void rwread_unlock(volatile unsigned int *rw) {
__asm__ __volatile__ (LOCK_PREFIX "incl %0" : "+m" (*rw) : : "memory");
}
-static inline void write_unlock(volatile unsigned int *rw) {
+static inline void rwwrite_unlock(volatile unsigned int *rw) {
__asm__ __volatile__ (LOCK_PREFIX "addl %1, %0"
: "+m" (*rw) : "i" (RW_LOCK_BIAS) : "memory");
}
: "+m" (*v));
}
-static inline int atomic_sub_and_test(int i, unsigned int *v) {
+static inline int atomic_sub_and_test(int i, volatile unsigned int *v) {
unsigned char c;
__asm__ __volatile__ (LOCK_PREFIX "subl %2,%0; sete %1"
#define atomic_read(v) (*v)
-static inline int read_trylock(volatile unsigned int *lock) {
+static inline int rwread_trylock(volatile unsigned int *lock) {
atomic_dec(lock);
if (atomic_read(lock) >= 0)
return 1; //can aquire a new read lock
return 0; //failure
}
-static inline int write_trylock(volatile unsigned int *lock) {
- if (atomic_sub_and_test(RW_LOCK_BIAS, *lock)) {
+static inline int rwwrite_trylock(volatile unsigned int *lock) {
+ if (atomic_sub_and_test(RW_LOCK_BIAS, lock)) {
return 1; // get a write lock
}
- atomic_add(RW_LOCK_BIAS, *lock);
+ atomic_add(RW_LOCK_BIAS, lock);
return 0; // failed to acquire a write lock
}
#endif
#endif
#ifdef DELAYCOMP
-__thread chashlistnode_t *dc_c_table;
-__thread chashlistnode_t *dc_c_list;
+__thread dchashlistnode_t *dc_c_table;
+__thread dchashlistnode_t *dc_c_list;
__thread unsigned int dc_c_size;
__thread unsigned INTPTR dc_c_mask;
__thread unsigned int dc_c_numelements;
__thread unsigned int dc_c_threshold;
__thread double dc_c_loadfactor;
-__thread cliststruct_t *dc_c_structs;
+__thread dcliststruct_t *dc_c_structs;
void dc_t_chashCreate(unsigned int size, double loadfactor) {
- chashtable_t *ctable;
- chashlistnode_t *nodes;
+ dchashlistnode_t *nodes;
int i;
// Allocate space for the hash table
- dc_c_table = calloc(size, sizeof(chashlistnode_t));
+ dc_c_table = calloc(size, sizeof(dchashlistnode_t));
dc_c_loadfactor = loadfactor;
dc_c_size = size;
dc_c_threshold=size*loadfactor;
dc_c_mask = (size << 4)-1;
- dc_c_structs=calloc(1, sizeof(cliststruct_t));
+ dc_c_structs=calloc(1, sizeof(dcliststruct_t));
dc_c_numelements = 0; // Initial number of elements in the hash
dc_c_list=NULL;
}
void dc_t_chashreset() {
- chashlistnode_t *ptr = dc_c_table;
+ dchashlistnode_t *ptr = dc_c_table;
int i;
if (dc_c_numelements<(dc_c_size>>4)) {
- chashlistnode_t *top=&ptr[dc_c_size];
- chashlistnode_t *tmpptr=dc_c_list;
+ dchashlistnode_t *top=&ptr[dc_c_size];
+ dchashlistnode_t *tmpptr=dc_c_list;
while(tmpptr!=NULL) {
- chashlistnode_t *next=tmpptr->lnext;
+ dchashlistnode_t *next=tmpptr->lnext;
if (tmpptr>=ptr&&tmpptr<top) {
//zero in list
tmpptr->key=NULL;
tmpptr=next;
}
} else {
- bzero(dc_c_table, sizeof(chashlistnode_t)*dc_c_size);
+ bzero(dc_c_table, sizeof(dchashlistnode_t)*dc_c_size);
}
while(dc_c_structs->next!=NULL) {
- cliststruct_t *next=dc_c_structs->next;
+ dcliststruct_t *next=dc_c_structs->next;
free(dc_c_structs);
dc_c_structs=next;
}
//Store objects and their pointers into hash
void dc_t_chashInsertOnce(void * key, void *val) {
- chashlistnode_t *ptr;
+ dchashlistnode_t *ptr;
if (key==NULL)
return;
dc_c_list=ptr;
dc_c_numelements++;
} else { // Insert in the beginning of linked list
- chashlistnode_t * node;
- chashlistnode_t *search=ptr;
+ dchashlistnode_t * node;
+ dchashlistnode_t *search=ptr;
//make sure it isn't here
do {
dc_c_structs->num++;
} else {
//get new list
- cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t));
+ dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
+ tcl->next=dc_c_structs;
+ dc_c_structs=tcl;
+ node=&tcl->array[0];
+ tcl->num=1;
+ }
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next=node;
+ node->lnext=dc_c_list;
+ dc_c_list=node;
+ }
+}
+
+#ifdef STMARRAY
+//Store objects and their pointers into hash
+void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) {
+ dchashlistnode_t *ptr;
+
+ if (key==NULL)
+ return;
+
+ if(dc_c_numelements > (dc_c_threshold)) {
+ //Resize
+ unsigned int newsize = dc_c_size << 1;
+ dc_t_chashResize(newsize);
+ }
+
+ ptr = &dc_c_table[(((unsigned INTPTR)key^intkey)&dc_c_mask)>>4];
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->intkey=intkey;
+ ptr->val=val;
+ ptr->lnext=dc_c_list;
+ dc_c_list=ptr;
+ dc_c_numelements++;
+ } else { // Insert in the beginning of linked list
+ dchashlistnode_t * node;
+ dchashlistnode_t *search=ptr;
+
+ //make sure it isn't here
+ do {
+ if(search->key == key&&search->intkey==intkey) {
+ return;
+ }
+ search=search->next;
+ } while(search != NULL);
+
+ dc_c_numelements++;
+ if (dc_c_structs->num<NUMCLIST) {
+ node=&dc_c_structs->array[dc_c_structs->num];
+ dc_c_structs->num++;
+ } else {
+ //get new list
+ dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
tcl->next=dc_c_structs;
dc_c_structs=tcl;
node=&tcl->array[0];
tcl->num=1;
}
node->key = key;
+ node->intkey = intkey;
node->val = val;
node->next = ptr->next;
ptr->next=node;
dc_c_list=node;
}
}
+#endif
unsigned int dc_t_chashResize(unsigned int newsize) {
- chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
+ dchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
unsigned int oldsize;
int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
unsigned int i,index;
oldsize = dc_c_size;
dc_c_list=NULL;
- if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
+ if((node = calloc(newsize, sizeof(dchashlistnode_t))) == NULL) {
printf("Calloc error %s %d\n", __FILE__, __LINE__);
return 1;
}
isfirst = 1;
do { //Inner loop to go through linked lists
void * key;
- chashlistnode_t *tmp,*next;
+#ifdef STMARRAY
+ unsigned int intkey;
+#endif
+ dchashlistnode_t *tmp,*next;
if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
break; //key = val =0 for element if not present within the hash table
}
+#ifdef STMARRAY
+ intkey=curr->intkey;
+ index = (((unsigned INTPTR)key^intkey) & mask) >>4;
+#else
index = (((unsigned INTPTR)key) & mask) >>4;
+#endif
tmp=&node[index];
next = curr->next;
// Insert into the new table
if(tmp->key == 0) {
tmp->key = key;
+#ifdef STMARRAY
+ tmp->intkey = intkey;
+#endif
tmp->val = curr->val;
tmp->lnext=dc_c_list;
dc_c_list=tmp;
//Delete the entire hash table
void dc_t_chashDelete() {
int i;
- cliststruct_t *ptr=dc_c_structs;
+ dcliststruct_t *ptr=dc_c_structs;
while(ptr!=NULL) {
- cliststruct_t *next=ptr->next;
+ dcliststruct_t *next=ptr->next;
free(ptr);
ptr=next;
}
// Search for an address for a given oid
INLINE void * dc_t_chashSearch(void * key) {
//REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
- chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+ dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
do {
if(node->key == key) {
return NULL;
}
+#ifdef STMARRAY
+// Search for an address for a given oid
+INLINE void * dc_t_chashSearchArray(void * key, unsigned int intkey) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+ dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key^intkey) & dc_c_mask)>>4];
+
+ do {
+ if(node->key == key && node->intkey==intkey) {
+ return node->val;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return NULL;
+}
+#endif
+
#endif
void t_chashCreate(unsigned int size, double loadfactor) {
#endif
#ifdef DELAYCOMP
-extern __thread chashlistnode_t *dc_c_table;
-extern __thread chashlistnode_t *dc_c_list;
+
+typedef struct dchashlistnode {
+ void * key;
+ unsigned int intkey;
+ void * val; //this can be cast to another type or used to point to a larger structure
+ struct dchashlistnode *next;
+ struct dchashlistnode *lnext;
+} dchashlistnode_t;
+
+#define NUMDCLIST 250
+typedef struct dclist {
+ struct dchashlistnode array[NUMDCLIST];
+ int num;
+ struct dclist *next;
+} dcliststruct_t;
+
+extern __thread dchashlistnode_t *dc_c_table;
+extern __thread dchashlistnode_t *dc_c_list;
extern __thread unsigned int dc_c_size;
extern __thread unsigned INTPTR dc_c_mask;
extern __thread unsigned int dc_c_numelements;
extern __thread unsigned int dc_c_threshold;
extern __thread double dc_c_loadfactor;
-extern __thread cliststruct_t *dc_c_structs;
+extern __thread dcliststruct_t *dc_c_structs;
void dc_t_chashCreate(unsigned int size, double loadfactor);
void dc_t_chashInsertOnce(void * key, void *val);
#define TRANS_SOFT_ABORT 12
#define TRANS_ABORT 13
#define TRANS_COMMIT 14
-#define TRANS_ABORT_RETRY 15
+#define TRANS_ABORT_RETRY 15
/* ========================
* Library header files
#endif
#define likely(x) x
+#define unlikely(x) x
extern void * curr_heapbase;
extern void * curr_heapptr;
#ifdef DELAYCOMP
ptrstack.prev=stackptr;
stackptr=(struct garbagelist *) &ptrstack;
+#ifdef STMARRAY
+ arraystack.prev=stackptr;
+ stackptr=(struct garbagelist *) &arraystack;
+#endif
#endif
#ifdef GARBAGESTATS
//just append us to the list
ptrstack.prev=ptr;
ptr=(struct garbagelist *) &ptrstack;
+#ifdef STMARRAY
+ arraystack.prev=ptr;
+ ptr=(struct garbagelist *) &arraystack;
+#endif
#endif
#ifndef MAC
litem.stackptr=ptr;
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
- int a=mprotect((downpage(&ptrstack.array[MAXPOINTERS])), 4096, PROT_NONE);
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
+ int a=mprotect((downpage(&ptrstack.buffer[0])), 4096, PROT_NONE);
if (a==-1)
perror("ptrstack");
a=mprotect(downpage(&primstack.array[MAXVALUES]), 4096, PROT_NONE);
a=mprotect(downpage(&branchstack.array[MAXBRANCHES]), 4096, PROT_NONE);
if (a==-1)
perror("branchstack");
+#ifdef STMARRAY
+ a=mprotect(downpage(&arraystack.index[MAXARRAY]), 4096, PROT_NONE);
+ if (a==-1)
+ perror("arraystack");
+#endif
#endif
#ifdef STMSTATS
trec=calloc(1, sizeof(threadrec_t));
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
- int a=mprotect(downpage(&ptrstack.array[MAXPOINTERS]), 4096, PROT_NONE);
+#ifdef STMARRAY
+ arraystack.count=0;
+#endif
+ int a=mprotect(downpage(&ptrstack.buffer[0]), 4096, PROT_NONE);
if (a==-1)
perror("ptrstack");
a=mprotect(downpage(&primstack.array[MAXVALUES]), 4096, PROT_NONE);
a=mprotect(downpage(&branchstack.array[MAXBRANCHES]), 4096, PROT_NONE);
if (a==-1)
perror("branchstack");
+#ifdef STMARRAY
+ a=mprotect(downpage(&arraystack.index[MAXARRAY]), 4096, PROT_NONE);
+ if (a==-1)
+ perror("arraystack");
+#endif
#endif
___Thread____NNR____staticStart____L___Thread___((struct ___Thread____NNR____staticStart____L___Thread____params *)p);
objstrDelete(t_cache);