switch to spaces only..
[IRC.git] / Robust / src / Runtime / DSTM / interface / gCollect.c
1 #include "gCollect.h"
2 #include "altprelookup.h"
3
4
5 extern pthread_mutex_t prefetchcache_mutex; //Mutex to lock Prefetch Cache
6 extern prehashtable_t pflookup; //Global prefetch cache  lookup table
7 prefetchNodeInfo_t pNodeInfo; //Global prefetch holding metadata
8
9 #define OSUSED(x) (((unsigned int)(x)->top)-((unsigned int) (x+1)))
10 #define OSFREE(x) ((x)->size-OSUSED(x))
11
12 void initializePCache() {
13   objstr_t * os=objstrCreate(DEFAULT_OBJ_STORE_SIZE);
14   pNodeInfo.oldptr = os;
15   pNodeInfo.newptr = os;
16   pNodeInfo.os_count = 1; //for prefetch cache allocated by objstralloc in trans.c file
17   pNodeInfo.oldstale=NULL;
18   pNodeInfo.newstale=NULL;
19   pNodeInfo.stale_count=0;
20   pNodeInfo.stall=0;
21 }
22
23 objstr_t * getObjStr(unsigned int size) {
24   if (pNodeInfo.stall>0)
25     pNodeInfo.stall--;
26   if (size<=DEFAULT_OBJ_STORE_SIZE&&pNodeInfo.stale_count>STALE_MINTHRESHOLD&&pNodeInfo.stall==0) {
27     //recycle
28     objstr_t * tmp=pNodeInfo.oldstale;
29     pNodeInfo.oldstale=pNodeInfo.oldstale->prev;
30     if (pNodeInfo.oldstale==NULL)
31       pNodeInfo.newstale=NULL;
32     pNodeInfo.stale_count--;
33     tmp->top=tmp+1;
34     tmp->prev=NULL;
35     return tmp;
36   } else {
37     int allocsize=(size>DEFAULT_OBJ_STORE_SIZE) ? size : DEFAULT_OBJ_STORE_SIZE;
38     return objstrCreate(allocsize);
39   }
40 }
41
42 void *prefetchobjstrAlloc(unsigned int size) {
43   //try existing space in first two OS
44   objstr_t *os=pNodeInfo.newptr;
45   if ((size&7)!=0)
46     size+=(8-(size&7));
47   if (size<=OSFREE(os)) {
48     void *tmp=os->top;
49     os->top=((char *)os->top)+size;
50     return tmp;
51   }
52   if ((os=os->next)!=NULL&&(size<=OSFREE(os))) {
53     void *tmp=os->top;
54     os->top=((char *)os->top)+size;
55     return tmp;
56   }
57   //need to allocate new space
58   objstr_t *tmp=getObjStr(size);;
59
60   //link new node in
61   tmp->next=pNodeInfo.newptr;
62   pNodeInfo.newptr->prev=tmp;
63   pNodeInfo.newptr=tmp;
64   pNodeInfo.os_count++;
65
66   if (pNodeInfo.os_count>PREFETCH_FLUSH_THRESHOLD) {
67     //remove oldest from linked list
68     objstr_t *tofree=pNodeInfo.oldptr;
69     pNodeInfo.oldptr=tofree->prev;
70     pNodeInfo.os_count--;
71     //need to flush cache
72     clearBlock(tofree);
73     if (pNodeInfo.newstale==NULL) {
74       //first store
75       pNodeInfo.newstale=pNodeInfo.oldstale=tofree;
76       tofree->prev=NULL;
77       pNodeInfo.stale_count++;
78     } else {
79       //just add it to the list
80       pNodeInfo.newstale->prev=tofree;
81       pNodeInfo.newstale=tofree;
82       pNodeInfo.stale_count++;
83     }
84     if (pNodeInfo.stale_count>STALE_MAXTHRESHOLD) {
85       //need to toss a store
86       tofree=pNodeInfo.oldstale;
87       pNodeInfo.oldstale=tofree->prev;
88       pNodeInfo.stale_count--;
89       free(tofree);
90     }
91   }
92
93   void *ptr=tmp->top;
94   tmp->top=((char *)tmp->top)+size;
95   return ptr;
96 }
97
98 void clearBlock(objstr_t *block) {
99
100   unsigned long int tmpbegin=(unsigned int)block;
101   unsigned long int tmpend=(unsigned int)block->top;
102   int i, j;
103   prehashlistnode_t *ptr;
104
105   int lockindex=0;
106   ptr = pflookup.table;
107   volatile unsigned int * lockptr_current=&pflookup.larray[lockindex].lock;
108   while(!write_trylock(lockptr_current)) {
109     sched_yield();
110   }
111
112   for(i = 0; i<pflookup.size; i++) {
113
114     prehashlistnode_t *orig=&ptr[i];
115     prehashlistnode_t *curr = orig;
116     prehashlistnode_t *next=curr->next;
117     for(; next != NULL; curr=next, next = next->next) {
118       unsigned int val=(unsigned int)next->val;
119       if ((val>=tmpbegin)&(val<tmpend)) {
120         prehashlistnode_t *tmp=curr->next=next->next;
121         free(next);
122         next=curr;
123         //loop condition is broken now...need to check before incrementing
124         //      if (next==NULL)
125         // break;
126       }
127     }
128     {
129       unsigned int val=(unsigned int)orig->val;
130       if ((val>=tmpbegin)&(val<tmpend)) {
131         if (orig->next==NULL) {
132           orig->key=0;
133           orig->val=NULL;
134         } else {
135           next=orig->next;
136           orig->val=next->val;
137           orig->key=next->key;
138           orig->next=next->next;
139           free(next);
140         }
141       }
142     }
143
144     if(((i+1)&(pflookup.mask>>4))==0 && (i+1)<pflookup.size) {
145       // try to grab new lock
146       lockindex++;
147       volatile unsigned int * lockptr_new=&pflookup.larray[lockindex].lock;
148       while(!write_trylock(lockptr_new)) {
149         sched_yield();
150       }
151       write_unlock(lockptr_current);
152       lockptr_current=lockptr_new;
153     }
154
155   } // end of for (pflokup)
156
157   write_unlock(lockptr_current);
158 }
159
160 objstr_t *allocateNew(unsigned int size) {
161   objstr_t *tmp;
162   if((tmp = (objstr_t *) calloc(1, (sizeof(objstr_t) +size))) == NULL) {
163     printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
164     return NULL;
165   }
166   tmp->size = size;
167   tmp->top = (void *)(((unsigned int)tmp) + sizeof(objstr_t) + size);
168   //Insert newly allocated block into linked list of prefetch cache
169   // Update maxsize of prefetch objstr blocks
170   return tmp;
171 }