//Barrier for synchronizing moves
Barrier barr;
int id;
- atomic {
- id = threadid;
- }
+ id = threadid;
barr = new Barrier("127.0.0.1");
Random rand = new Random(id);
// Init land and place rocks in boundaries
GameMap[][] world;
- atomic {
- mybarr = new BarrierServer(numThreads);
- world = new GameMap[ROW][COLUMN];
- int i, j;
- for (i = 0; i < ROW; i++) {
- for (j = 0; j < COLUMN; j++) {
- world[i][j] = new GameMap();
- if (j == 0 || j == COLUMN-1) {
- RockType r = new RockType();
- world[i][j].putRock(r);
- }
- if (i == 0 || i == ROW-1) {
- RockType r = new RockType();
- world[i][j].putRock(r);
- }
+ mybarr = new BarrierServer(numThreads);
+ world = new GameMap[ROW][COLUMN];
+
+ for (int i = 0; i < ROW; i++) {
+ for (int j = 0; j < COLUMN; j++) {
+ world[i][j] = new GameMap();
+ if (j == 0 || j == COLUMN-1) {
+ RockType r = new RockType();
+ world[i][j].putRock(r);
+ }
+ if (i == 0 || i == ROW-1) {
+ RockType r = new RockType();
+ world[i][j].putRock(r);
+ }
}
- }
}
mybarr.start();
/* Set up threads */
RainForest[] rf;
- atomic {
- rf = new RainForest[numThreads];
- for(int i=0; i<numThreads; i++) {
+ rf = new RainForest[numThreads];
+ for(int i=0; i<numThreads; i++) {
rf[i] = new RainForest(world, mybarr, i, numThreads);
- }
}
/* Barrier Server waits for messages */
boolean waitforthreaddone = true;
while(waitforthreaddone) {
- atomic {
if(mybarr.done)
- waitforthreaddone = false;
- }
+ waitforthreaddone = false;
}
/* Start threads */
Node.java \
AStarPathFinder.java
-FLAGS=-singleTM -nooptimize -mainclass ${MAINCLASS} -debug -transstats
+FLAGS=-singleTM -optimize -mainclass ${MAINCLASS} -debug -transstats -joptimize -profile
default:
cpp ${MAINCLASS}.java > tmp1${MAINCLASS}.java
#include "garbage.h"
/* Thread transaction variables */
__thread objstr_t *t_cache;
+__thread struct objlist * newobjs;
#ifdef TRANSSTATS
int numTransCommit = 0;
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->lock=RW_LOCK_BIAS;
tmp->version = 1;
STATUS(tmp)=NEW;
- t_chashInsert((unsigned int) retval, retval);
+ // don't insert into table
+ if (newobjs->offset<MAXOBJLIST) {
+ newobjs->objs[newobjs->offset++]=retval;
+ } else {
+ struct objlist *tmp=malloc(sizeof(struct objlist));
+ tmp->next=newobjs;
+ tmp->objs[0]=retval;
+ tmp->offset=1;
+ newobjs=tmp;
+ }
return retval; //want space after object header
}
objheader_t *objcopy;
int size;
+ //quick case for new objects
+ if (((struct ___Object___ *)oid)->___objstatus___ & NEW)
+ return oid;
+
/* Read from the main heap */
objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
if(read_trylock(&header->lock)) { //Can further acquire read locks
}
}
+void freenewobjs() {
+ struct objlist *ptr=newobjs;
+ while(ptr->next!=NULL) {
+ struct objlist *tmp=ptr->next;
+ free(ptr);
+ ptr=tmp;
+ }
+ ptr->offset=0;
+ newobjs=ptr;
+}
+
/* ================================================================
* transCommit
* - This function initiates the transaction commit process
#ifdef TRANSSTATS
numTransAbort++;
#endif
+ freenewobjs();
objstrDelete(t_cache);
t_chashDelete();
return TRANS_ABORT;
#ifdef TRANSSTATS
numTransCommit++;
#endif
+ freenewobjs();
objstrDelete(t_cache);
t_chashDelete();
return 0;
unsigned int version = headeraddr->version;
objheader_t *header=(objheader_t *) (((char *)curr->key)-sizeof(objheader_t));
- if(STATUS(headeraddr) & NEW) {
- STATUS(headeraddr)=0;
- } else if(STATUS(headeraddr) & DIRTY) {
+ 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 */
objheader_t *header;
void *ptrcreate;
int i;
-
+ struct objlist *ptr=newobjs;
+ while(ptr!=NULL) {
+ int max=ptr->offset;
+ for(i=0;i<max;i++) {
+ //clear the new flag
+ ((struct ___Object___ *)ptr->objs[i])->___objstatus___=0;
+ }
+ ptr=ptr->next;
+ }
+
/* Copy from transaction cache -> main object store */
for (i = 0; i < *numoidwrlocked; i++) {
/* Read from the main heap */
--- /dev/null
+#include "stmlookup.h"
+
+__thread chashlistnode_t *c_table;
+__thread unsigned int c_size;
+__thread unsigned int c_mask;
+__thread unsigned int c_numelements;
+__thread unsigned int c_threshold;
+__thread double c_loadfactor;
+
+void t_chashCreate(unsigned int size, double loadfactor) {
+ chashtable_t *ctable;
+ chashlistnode_t *nodes;
+ int i;
+
+ // Allocate space for the hash table
+
+
+ c_table = calloc(size, sizeof(chashlistnode_t));
+ c_loadfactor = loadfactor;
+ c_size = size;
+ c_threshold=size*loadfactor;
+ c_mask = (size << 3)-1;
+ c_numelements = 0; // Initial number of elements in the hash
+}
+
+chashtable_t *chashCreate(unsigned int size, double loadfactor) {
+ chashtable_t *ctable;
+ chashlistnode_t *nodes;
+ int i;
+
+ if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return NULL;
+ }
+
+ // Allocate space for the hash table
+ if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ free(ctable);
+ return NULL;
+ }
+
+ ctable->table = nodes;
+ ctable->loadfactor = loadfactor;
+ ctable->size = size;
+ ctable->threshold=size*loadfactor;
+ ctable->mask = (size << 3)-1;
+ ctable->numelements = 0; // Initial number of elements in the hash
+
+
+ return ctable;
+}
+
+//Finds the right bin in the hash table
+static INLINE unsigned int chashFunction(chashtable_t *table, unsigned int key) {
+ return ( key & (table->mask))>>3; //throw away low order bit
+}
+
+//Store objects and their pointers into hash
+void chashInsert(chashtable_t *table, unsigned int key, void *val) {
+ chashlistnode_t *ptr;
+
+ if(table->numelements > (table->threshold)) {
+ //Resize
+ unsigned int newsize = table->size << 1;
+ chashResize(table,newsize);
+ }
+
+ ptr = &table->table[(key&table->mask)>>3];
+ table->numelements++;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert in the beginning of linked list
+ chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t));
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next=node;
+ }
+}
+
+// Search for an address for a given oid
+INLINE void * chashSearch(chashtable_t *table, unsigned int key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+ chashlistnode_t *node = &table->table[(key & table->mask)>>3];
+
+ do {
+ if(node->key == key) {
+ return node->val;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return NULL;
+}
+
+//Store objects and their pointers into hash
+void t_chashInsert(unsigned int key, void *val) {
+ chashlistnode_t *ptr;
+
+
+ if(c_numelements > (c_threshold)) {
+ //Resize
+ unsigned int newsize = c_size << 1;
+ t_chashResize(newsize);
+ }
+
+ ptr = &c_table[(key&c_mask)>>3];
+ c_numelements++;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert in the beginning of linked list
+ chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t));
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next=node;
+ }
+}
+
+// Search for an address for a given oid
+INLINE void * t_chashSearch(unsigned int key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+ chashlistnode_t *node = &c_table[(key & c_mask)>>3];
+
+ do {
+ if(node->key == key) {
+ return node->val;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return NULL;
+}
+
+unsigned int chashRemove(chashtable_t *table, unsigned int key) {
+ return chashRemove2(table, key)==NULL;
+
+}
+
+void * chashRemove2(chashtable_t *table, unsigned int key) {
+ int index;
+ chashlistnode_t *curr, *prev;
+ chashlistnode_t *ptr, *node;
+ void *value;
+
+ ptr = table->table;
+ index = chashFunction(table,key);
+ curr = &ptr[index];
+
+ for (; curr != NULL; curr = curr->next) {
+ if (curr->key == key) { // Find a match in the hash table
+ table->numelements--; // Decrement the number of elements in the global hashtable
+ if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of chashlistnode_t
+ curr->key = 0;
+ value=curr->val;
+ curr->val = NULL;
+ } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t connected
+ curr->key = curr->next->key;
+ value=curr->val;
+ curr->val = curr->next->val;
+ node = curr->next;
+ curr->next = curr->next->next;
+ free(node);
+ } else { // Regular delete from linked listed
+ prev->next = curr->next;
+ value=curr->val;
+ free(curr);
+ }
+ return value;
+ }
+ prev = curr;
+ }
+ return NULL;
+}
+
+unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
+ chashlistnode_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;
+ unsigned int mask;
+
+ ptr = table->table;
+ oldsize = table->size;
+
+ if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ table->table = node; //Update the global hashtable upon resize()
+ table->size = newsize;
+ table->threshold = newsize * table->loadfactor;
+ mask=table->mask = (newsize << 3)-1;
+
+ for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
+ curr = &ptr[i];
+ isfirst = 1;
+ do { //Inner loop to go through linked lists
+ unsigned int key;
+ chashlistnode_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
+ }
+ next = curr->next;
+ index = (key & mask) >>3;
+ tmp=&node[index];
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = curr->key;
+ tmp->val = curr->val;
+ if (!isfirst) {
+ free(curr);
+ }
+ }/*
+ NOTE: Add this case if you change this...
+ This case currently never happens because of the way things rehash....
+ else if (isfirst) {
+ chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
+ newnode->key = curr->key;
+ newnode->val = curr->val;
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } */
+ else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ }
+
+ isfirst = 0;
+ curr = next;
+ } while(curr!=NULL);
+ }
+
+ free(ptr); //Free the memory of the old hash table
+ return 0;
+}
+
+unsigned int 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
+ unsigned int oldsize;
+ int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
+ unsigned int i,index;
+ unsigned int mask;
+
+ ptr = c_table;
+ oldsize = c_size;
+
+ if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ c_table = node; //Update the global hashtable upon resize()
+ c_size = newsize;
+ c_threshold = newsize * c_loadfactor;
+ mask=c_mask = (newsize << 3)-1;
+
+ for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
+ curr = &ptr[i];
+ isfirst = 1;
+ do { //Inner loop to go through linked lists
+ unsigned int key;
+ chashlistnode_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
+ }
+ next = curr->next;
+ index = (key & mask) >>3;
+ tmp=&node[index];
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = curr->key;
+ tmp->val = curr->val;
+ if (!isfirst) {
+ free(curr);
+ }
+ }/*
+ NOTE: Add this case if you change this...
+ This case currently never happens because of the way things rehash....
+ else if (isfirst) {
+ chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
+ newnode->key = curr->key;
+ newnode->val = curr->val;
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } */
+ else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ }
+
+ isfirst = 0;
+ curr = next;
+ } while(curr!=NULL);
+ }
+
+ free(ptr); //Free the memory of the old hash table
+ return 0;
+}
+
+//Delete the entire hash table
+void chashDelete(chashtable_t *ctable) {
+ int i;
+ chashlistnode_t *ptr = ctable->table;
+
+ for(i=0 ; i<ctable->size ; i++) {
+ chashlistnode_t * curr = ptr[i].next;
+ while(curr!=NULL) {
+ chashlistnode_t * next = curr->next;
+ free(curr);
+ curr=next;
+ }
+ }
+ free(ptr);
+ free(ctable);
+}
+
+//Delete the entire hash table
+void t_chashDelete() {
+ int i;
+ chashlistnode_t *ptr = c_table;
+
+ for(i=0 ; i<c_size ; i++) {
+ chashlistnode_t * curr = ptr[i].next;
+ while(curr!=NULL) {
+ chashlistnode_t * next = curr->next;
+ free(curr);
+ curr=next;
+ }
+ }
+ free(ptr);
+ c_table=NULL;
+}
--- /dev/null
+#ifndef _CLOOKUP_H_
+#define _CLOOKUP_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define CLOADFACTOR 0.25
+#define CHASH_SIZE 1024
+
+#define INLINE inline __attribute__((always_inline))
+
+
+typedef struct chashlistnode {
+ unsigned int key;
+ void *val; //this can be cast to another type or used to point to a larger structure
+ struct chashlistnode *next;
+} chashlistnode_t;
+
+typedef struct chashtable {
+ chashlistnode_t *table; // points to beginning of hash table
+ unsigned int size;
+ unsigned int mask;
+ unsigned int numelements;
+ unsigned int threshold;
+ double loadfactor;
+} chashtable_t;
+
+
+void t_chashCreate(unsigned int size, double loadfactor);
+void t_chashInsert(unsigned int key, void *val);
+void * t_chashSearch(unsigned int key);
+unsigned int t_chashResize(unsigned int newsize);
+void t_chashDelete();
+
+/* Prototypes for hash*/
+chashtable_t *chashCreate(unsigned int size, double loadfactor);
+static unsigned int chashFunction(chashtable_t *table, unsigned int key);
+void chashInsert(chashtable_t *table, unsigned int key, void *val);
+void *chashSearch(chashtable_t *table, unsigned int key); //returns val, NULL if not found
+unsigned int chashRemove(chashtable_t *table, unsigned int key); //returns -1 if not found
+void * chashRemove2(chashtable_t *table, unsigned int key); //returns -1 if not found
+unsigned int chashResize(chashtable_t *table, unsigned int newsize);
+void chashDelete(chashtable_t *table);
+/* end hash */
+
+extern __thread chashlistnode_t *c_table;
+extern __thread unsigned int c_size;
+extern __thread unsigned int c_mask;
+extern __thread unsigned int c_numelements;
+extern __thread unsigned int c_threshold;
+extern __thread double c_loadfactor;
+
+#endif
#include <sys/time.h>
#include <errno.h>
#include "threadnotify.h"
-#include "clookup.h"
+#include "stmlookup.h"
#include "dsmlock.h"
/* ==================================
((void*)((((void *) x )!=NULL) ? (*((unsigned int *)&((struct ___Object___ *) x)->___objlocation___)) : 0))
#define STATUS(x) \
- *((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___objstatus___))
+ *((unsigned int *) &(((struct ___Object___ *)(((char *) x) + sizeof(objheader_t)))->___objstatus___))
#define STATUSPTR(x) \
- ((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___objstatus___))
+ ((unsigned int *) &(((struct ___Object___ *)(((char *) x) + sizeof(objheader_t)))->___objstatus___))
#define TYPE(x) \
((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->type
unsigned int inputvalue;\
if ((inputvalue=(unsigned int)y)==0) x=NULL;\
else { \
-chashlistnode_t * cnodetmp=&c_table[(inputvalue&c_mask)>>1]; \
+chashlistnode_t * cnodetmp=&c_table[(inputvalue&c_mask)>>3]; \
do { \
if (cnodetmp->key==inputvalue) {x=(void *)cnodetmp->val;break;} \
cnodetmp=cnodetmp->next;\
struct objstr *prev;
} objstr_t;
+#define MAXOBJLIST 512
+struct objlist {
+ int offset;
+ void * objs[MAXOBJLIST];
+ struct objlist * next;
+};
+
+extern __thread struct objlist * newobjs;
+
typedef struct newObjCreated {
unsigned int numcreated;
unsigned int *oidcreated;
}
#ifdef STM
+void fixobjlist(struct objlist * ptr) {
+ while(ptr!=NULL) {
+ int i;
+ for(i=0;i<ptr->offset;i++) {
+ SENQUEUE(ptr->objs[i], ptr->objs[i]);
+ }
+ ptr=ptr->next;
+ }
+}
+
void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
- unsigned int mask=(tc_size<<1)-1;
+ unsigned int mask=(tc_size<<3)-1;
chashlistnode_t *node=calloc(tc_size, sizeof(chashlistnode_t));
chashlistnode_t *ptr=*tc_table;
chashlistnode_t *curr;
}
next = curr->next;
- index = (((unsigned int)key) & mask) >>1;
+ index = (((unsigned int)key) & mask) >>3;
curr->key=(unsigned int)key;
tmp=&node[index];
#endif
#ifdef STM
- if (c_table!=NULL)
+ if (c_table!=NULL) {
fixtable(&c_table, c_size);
+ fixobjlist(newobjs);
+ }
#endif
/* Check current stack */
ENQUEUE(orig, listptr->locklist);
#endif
#ifdef STM
- if ((*listptr->tc_table)!=NULL)
+ if ((*listptr->tc_table)!=NULL) {
fixtable(listptr->tc_table, listptr->tc_size);
+ fixobjlist(listptr->objlist);
+ }
#endif
stackptr=listptr->stackptr;
listptr=listptr->next;
#ifdef STM
litem->tc_size=c_size;
litem->tc_table=&c_table;
+ litem->objlist=newobjs;
#endif
litem->prev=NULL;
pthread_mutex_lock(&gclistlock);
#endif
ptr=curr_heapptr;
if ((size&7)!=0)
- size+=(8-(size%8));
+ size=(size&~7)+8;
curr_heapptr+=size;
if (curr_heapptr>curr_heapgcpoint) {
if (curr_heapbase==0) {
#ifdef STM
unsigned int tc_size;
chashlistnode_t **tc_table;
+ struct objlist * objlist;
#endif
};
#ifdef THREADS
___Thread______staticStart____L___Thread___((struct ___Thread______staticStart____L___Thread____params *)p);
#else
+ newobjs=calloc(1, sizeof(struct objlist));
___Thread____NN____staticStart____L___Thread___((struct ___Thread____NN____staticStart____L___Thread____params *)p);
+ free(newobjs);
#endif
___this___=(struct ___Thread___ *) p[2];
#else
if $SINGLETM
then
EXTRAOPTIONS="$EXTRAOPTIONS -lpthread -DCOMPILER -I$DSMRUNTIME"
-FILES="$FILES $DSMRUNTIME/dsmlock.c $DSMRUNTIME/singleTMCommit.c $DSMRUNTIME/clookup.c $ROBUSTROOT/Runtime/thread.c"
+FILES="$FILES $DSMRUNTIME/dsmlock.c $DSMRUNTIME/singleTMCommit.c $DSMRUNTIME/stmlookup.c $ROBUSTROOT/Runtime/thread.c"
fi
if $ABORTREADERS