#include "chash.h"
#include "GenericHashtable.h"
#include <string.h>
-#if defined(THREADS) || defined(DSTM)
+#if defined(THREADS) || defined(DSTM) || defined(STM)
#include "thread.h"
#endif
#ifdef DSTM
#include "dstm.h"
#endif
+#ifdef STM
+#include "tm.h"
+#endif
#define NUMPTRS 100
-#define INITIALHEAPSIZE 8192*1024
+#define INITIALHEAPSIZE 32*1024*1024
#define GCPOINT(x) ((int)((x)*0.9))
/* This define takes in how full the heap is initially and returns a new heap size to use */
#define HEAPSIZE(x,y) (((int)((x)/0.6))+y)
extern struct RuntimeHash *fdtoobject;
#endif
-#if defined(THREADS) || defined(DSTM)
+#if defined(THREADS) || defined(DSTM) || defined(STM)
int needtocollect=0;
struct listitem * list=NULL;
int listcount=0;
#endif
//Need to check if pointers are transaction pointers
+//this also catches the special flag value of 1 for local copies
#ifdef DSTM
#define ENQUEUE(orig, dst) \
if ((!(((unsigned int)orig)&0x1))) { \
dst=copy; \
} \
}
+#elif STM
+#define ENQUEUE(orig, dst) \
+ if ((!(((unsigned int)orig)&0x1))) { \
+ if (orig>=curr_heapbase&&orig<curr_heaptop) { \
+ void *copy; \
+ if (gc_createcopy(orig,©)) \
+ enqueue(orig);\
+ dst=copy; \
+ } \
+ }
+#elif defined(FASTCHECK)
+#define ENQUEUE(orig, dst) \
+ if (((unsigned int)orig)!=1) { \
+ void *copy; \
+ if (gc_createcopy(orig,©)) \
+ enqueue(orig);\
+ dst=copy; }
#else
#define ENQUEUE(orig, dst) \
void *copy; \
void collect(struct garbagelist * stackptr) {
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
needtocollect=1;
pthread_mutex_lock(&gclistlock);
while(1) {
#endif
/* Check current stack */
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
{
struct listitem *listptr=list;
while(1) {
}
stackptr=stackptr->next;
}
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
/* Go to next thread */
if (listptr!=NULL) {
+#ifdef THREADS
void * orig=listptr->locklist;
ENQUEUE(orig, listptr->locklist);
+#endif
stackptr=listptr->stackptr;
listptr=listptr->next;
} else
}
#endif
+#ifdef FASTCHECK
+ ENQUEUE(___fcrevert___, ___fcrevert___);
+#endif
+
#ifdef TASK
{
/* Update objectsets */
int i;
for(i=0; i<NUMCLASSES; i++) {
-#ifdef MULTICORE
-#else
+#if !defined(MULTICORE)
struct parameterwrapper * p=objectqueues[i];
while(p!=NULL) {
struct ObjectHash * set=p->objectset;
}
}
+#ifndef FASTCHECK
if (forward!=NULL) {
struct cnode * ptr=forward->listhead;
while(ptr!=NULL) {
ptr=ptr->lnext;
}
}
+#endif
{
struct RuntimeNode * ptr=fdtoobject->listhead;
if (pointer==0) {
/* Array of primitives */
/* Do nothing */
-#ifdef DSTM
+#if defined(DSTM)||defined(FASTCHECK)
struct ArrayObject *ao=(struct ArrayObject *) ptr;
struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
/* Array of pointers */
struct ArrayObject *ao=(struct ArrayObject *) ptr;
struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
-#ifdef DSTM
+#if (defined(DSTM)||defined(FASTCHECK))
ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
#endif
}
#ifdef TASK
-
/* Fix up the references from tags. This can't be done earlier,
because we don't want tags to keep objects alive */
void fixtags() {
void * tomalloc(int size) {
void * ptr=to_heapptr;
- if ((size%4)!=0)
- size+=(4-(size%4));
+ if ((size&7)!=0)
+ size+=(8-(size%8));
to_heapptr+=size;
return ptr;
}
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
void checkcollect(void * ptr) {
- if (needtocollect) {
- struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
- pthread_mutex_lock(&gclock); // Wait for GC
- restartaftergc(tmp);
- pthread_mutex_unlock(&gclock);
-
- }
+ struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
+ pthread_mutex_lock(&gclock); // Wait for GC
+ restartaftergc(tmp);
+ pthread_mutex_unlock(&gclock);
}
#ifdef DSTM
-void checkcollect2(void * ptr, transrecord_t *trans) {
- if (needtocollect) {
- int ptrarray[]={1, (int)ptr, (int) trans->revertlist};
- struct listitem * tmp=stopforgc((struct garbagelist *)ptrarray);
- pthread_mutex_lock(&gclock); // Wait for GC
- restartaftergc(tmp);
- pthread_mutex_unlock(&gclock);
- trans->revertlist=(struct ___Object___*)ptrarray[2];
- }
+void checkcollect2(void * ptr) {
+ int ptrarray[]={1, (int)ptr, (int) revertlist};
+ struct listitem * tmp=stopforgc((struct garbagelist *)ptrarray);
+ pthread_mutex_lock(&gclock); // Wait for GC
+ restartaftergc(tmp);
+ pthread_mutex_unlock(&gclock);
+ revertlist=(struct ___Object___*)ptrarray[2];
}
#endif
struct listitem * stopforgc(struct garbagelist * ptr) {
struct listitem * litem=malloc(sizeof(struct listitem));
litem->stackptr=ptr;
+#ifdef THREADS
litem->locklist=pthread_getspecific(threadlocks);
+#endif
+#ifdef STM
+ litem->tc_size=c_size;
+ litem->tc_mask=c_mask;
+ litem->tc_table=&c_table;
+#endif
litem->prev=NULL;
pthread_mutex_lock(&gclistlock);
litem->next=list;
void restartaftergc(struct listitem * litem) {
pthread_mutex_lock(&gclistlock);
+#ifdef THREADS
pthread_setspecific(threadlocks, litem->locklist);
+#endif
if (litem->prev==NULL) {
list=litem->next;
} else {
void * mygcmalloc(struct garbagelist * stackptr, int size) {
void *ptr;
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
if (pthread_mutex_trylock(&gclock)!=0) {
struct listitem *tmp=stopforgc(stackptr);
pthread_mutex_lock(&gclock);
}
#endif
ptr=curr_heapptr;
- if ((size%4)!=0)
- size+=(4-(size%4));
+ if ((size&7)!=0)
+ size+=(8-(size%8));
curr_heapptr+=size;
if (curr_heapptr>curr_heapgcpoint) {
if (curr_heapbase==0) {
to_heaptop=to_heapbase+INITIALHEAPSIZE;
to_heapptr=to_heapbase;
ptr=curr_heapbase;
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
pthread_mutex_unlock(&gclock);
#endif
return ptr;
int last_heapsize=0;
if (lastgcsize>0) {
last_heapsize=HEAPSIZE(lastgcsize, size);
- if ((last_heapsize%4)!=0)
- last_heapsize+=(4-(last_heapsize%4));
+ if ((last_heapsize&7)!=0)
+ last_heapsize+=(8-(last_heapsize%8));
}
if (curr_heapsize>last_heapsize)
last_heapsize=curr_heapsize;
/* Not enough room :(, redo gc */
if (curr_heapptr>curr_heapgcpoint) {
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
pthread_mutex_unlock(&gclock);
#endif
return mygcmalloc(stackptr, size);
}
bzero(tmp, curr_heaptop-tmp);
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
pthread_mutex_unlock(&gclock);
#endif
return tmp;
}
} else {
-#if defined(THREADS)||defined(DSTM)
+#if defined(THREADS)||defined(DSTM)||defined(STM)
pthread_mutex_unlock(&gclock);
#endif
return ptr;