/* Array layout */
#define INDEXSHIFT 4 //must be at least 3 for doubles
#define DBLINDEXSHIFT INDEXSHIFT-1 //must be at least 3 for doubles
+#define INDEXLENGTH (1<<INDEXSHIFT)
+#define LOWMASK (INDEXLENGTH-1) //mast off low order bits
+#define HIGHMASK ~(LOWMASK) //mask off high order bits
+
+#define STMNONE 0
+#define STMCLEAN 1
+#define STMDIRTY 2
+
+#define MAXARRAYSIZE 2147483647
#define GETLOCKPTR(lock, array, byteindex) { \
lock=(int *)((char *)array-sizeof(objheader_t)-sizeof(int)*(byteindex>>DBLINDEXSHIFT)); \
}
+#define GETLOCKVAL(lock, array, byteindex) { \
+ lock=*(int *)((char *)array-sizeof(objheader_t)-sizeof(int)*(byteindex>>DBLINDEXSHIFT)); \
+ }
+
#define GETVERSIONPTR(version, array, byteindex) { \
version=(int *)((char *)array-sizeof(objheader_t)-sizeof(int)*(byteindex>>DBLINDEXSHIFT)-sizeof(int)); \
}
+
+#define STMGETARRAY(dst, array, index, type) { \
+ int byteindex=index*sizeof(type); \
+ int * lengthoff=&array->___length___; \
+ int *status; \
+ GETLOCKPTR(status, array, byteindex); \
+ if ((*status)==STMNONE) { \
+ arraycopy(array, byteindex); \
+ *status=STMCLEAN;}; \
+ dst=((type *)(((char *) lengthoff)+sizeof(int)))[index]; \
+ }
+
+#define STMSETARRAY(array, index, src, type) { \
+ int byteindex=index*sizeof(type); \
+ int * lengthoff=&array->___length___; \
+ int *status; \
+ GETLOCKPTR(status, array); \
+ if (*status==STMNONE) \
+ arraycopy(array, byteindex, sizeof(type)*(*lengthoff)); \
+ *status=STMDIRTY; \
+ ((type *)(((char *) lengthoff)+sizeof(int)))[index]=src; \
+ }
#endif
objheader_t *objcopy;
int size;
- /* Read from the main heap */
- //No lock for now
objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t));
- GETSIZE(size, header);
- size += sizeof(objheader_t);
- objcopy = (objheader_t *) objstrAlloc(size);
#ifdef STMSTATS
header->accessCount++;
if(header->riskyflag) {
header=needLock(header,gl);
}
#endif
+#ifdef STMARRAY
+ GETSIZE(size, header);
+ int type=TYPE(header);
+ if (type>=NUMCLASSES) {
+ int metasize=sizeof(int)*((((struct ArrayObject *)oid)->___length___*classsize[type])>>DBLINDEXSHIFT);
+ size += sizeof(objheader_t)+metasize;
+ char *tmpptr = (char *) objstrAlloc(size);
+ bzero(objcopy, metasize);//clear out stm data
+ objcopy=tmpptr+metasize;
+ A_memcpy(objcopy, header, sizeof(objheader_t)+sizeof(struct ArrayObject)); //copy the metadata and base array info
+ } else {
+ size += sizeof(objheader_t);
+ objcopy = (objheader_t *) objstrAlloc(size);
+ A_memcpy(objcopy, header, size);
+ }
+#else
+ GETSIZE(size, header);
+ size += sizeof(objheader_t);
+ objcopy = (objheader_t *) objstrAlloc(size);
A_memcpy(objcopy, header, size);
+#endif
#ifdef STMSTATS
/* keep track of the object's access sequence in a transaction */
objheader_t *tmpheader = objcopy;
tmpheader->accessCount = ++t_objnumcount;
#endif
-
/* Insert into cache's lookup table */
STATUS(objcopy)=0;
if (((unsigned INTPTR)oid)<((unsigned INTPTR ) curr_heapbase)|| ((unsigned INTPTR)oid) >((unsigned INTPTR) curr_heapptr))
return &objcopy[1];
}
+#ifdef STMARRAY
+//caller needs to mark data as present
+ void arraycopy(struct ArrayObject *oid, int byteindex) {
+ struct ArrayObject * orig=oid->___objlocation___;
+ int baseoffset=byteindex&HIGHMASK;
+ A_memcpy(((char *)&oid[1])+baseoffset, ((char *)&orig[1])+baseoffset, INDEXLENGTH);
+ if (oid->lowoffset>baseoffset)
+ oid->lowoffset=baseoffset;
+ if (oid->highoffset<baseoffset)
+ oid->highoffset=baseoffset;
+ }
+#endif
+
void freenewobjs() {
struct objlist *ptr=newobjs;
while(ptr->next!=NULL) {
__attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
#ifdef STMARRAY
struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(int)*(((length*classsize[type])>>DBLINDEXSHIFT)), (length*classsize[type])>>DBLINDEXSHIFT);
+ v->highindex=-1;
+ v->lowindex=MAXARRAYSIZE;
#else
struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
#endif