start of new file
[IRC.git] / Robust / src / Runtime / DSTM / interface / gCollect.c
1 #include "gCollect.h"
2 #include "prelookup.h"
3
4 extern objstr_t *prefetchcache; //Global Prefetch cache
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 void initializePCache() {
10   pNodeInfo = calloc(1, sizeof(prefetchNodeInfo_t)); //Not freed yet
11   pNodeInfo->oldptr = prefetchcache;
12   pNodeInfo->newptr = NULL;
13   pNodeInfo->num_old_objstr = 1; //for prefetch cache allocated by objstralloc in trans.c file
14   pNodeInfo->maxsize = DEFAULT_OBJ_STORE_SIZE;
15 }
16
17 void *prefetchobjstrAlloc(unsigned int size) {
18   void * ptr = NULL;
19   if(pNodeInfo->num_old_objstr <= PREFETCH_FLUSH_COUNT_THRESHOLD) {
20     //regular allocation 
21     if((ptr = normalPrefetchAlloc(prefetchcache, size)) == NULL) {
22       printf("Error: %s() prefetch cache alloc error %s, %d\n", __func__, __FILE__, __LINE__);
23       return NULL;
24     }
25     return ptr;
26   } else {
27     // Iterate through available blocks to see if size can be allocated
28     if((ptr = lookUpFreeSpace(pNodeInfo->newptr, pNodeInfo->oldptr, size)) != NULL) {
29       return ptr;
30     } else { //allocate new block if size not available
31       if(size >= pNodeInfo->maxsize) {
32         if((ptr = allocateNew(size)) == NULL) {
33           printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
34           return NULL;
35         }
36         return ptr;
37       } else { //If size less then reclaim old blocks
38         clearNBlocks(pNodeInfo->oldptr, pNodeInfo->newptr);
39         //update oldptr and newptr
40         updatePtrs();
41         //look for free space if available in the free blocks
42         if((ptr = lookUpFreeSpace(pNodeInfo->newptr, pNodeInfo->oldptr, size)) != NULL) {
43           return ptr;
44         } else {
45           if((ptr = allocateNew(size)) == NULL) {
46             printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
47             return NULL;
48           }
49           return ptr;
50         }
51       }
52     }
53   }
54 }
55
56 void *normalPrefetchAlloc(objstr_t *store, unsigned int size) {
57   void *tmp;
58   while (1) {
59     if(((unsigned int)store->top - (((unsigned int)store) + sizeof(objstr_t)) + size) <= store->size) { //store not full
60       tmp = store->top;
61       store->top += size;
62       return tmp;
63     }   
64     //store full
65     if(store->next == NULL) {
66       //end of list, all full
67       if(size > DEFAULT_OBJ_STORE_SIZE) {
68         //in case of large objects
69         if((store->next = (objstr_t *) calloc(1,(sizeof(objstr_t) + size))) == NULL) {
70           printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
71           return NULL;
72         }   
73         store = store->next;
74         store->size = size;
75       } else {
76         if((store->next = (objstr_t *) calloc(1, (sizeof(objstr_t) + DEFAULT_OBJ_STORE_SIZE))) == NULL) {
77           printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
78           return NULL;
79         }   
80         store = store->next;
81         store->size = DEFAULT_OBJ_STORE_SIZE;
82       }
83       //Update maxsize of objstr blocks, num of blocks and newptr 
84       pNodeInfo->num_old_objstr++;
85       if(pNodeInfo->num_old_objstr <= PREFETCH_FLUSH_COUNT_THRESHOLD/2)
86         pNodeInfo->newptr = store;
87       if(pNodeInfo->maxsize < size)
88         pNodeInfo->maxsize = size;
89       store->top = (void *)(((unsigned int)store) + sizeof(objstr_t) + size);
90       return (void *)(((unsigned int)store) + sizeof(objstr_t));
91     } else {
92       store = store->next;
93     }
94   }
95 }
96
97 void *lookUpFreeSpace(void *startAddr, void *endAddr, int size) {
98   objstr_t *ptr;
99   void *tmp;
100   ptr = (objstr_t *) (startAddr);
101   while(ptr != NULL && ((unsigned long int)ptr!= (unsigned long int)endAddr)) { 
102     if(((unsigned int)ptr->top - (((unsigned int)ptr) + sizeof(objstr_t)) + size) <= ptr->size) { //store not full
103       tmp = ptr->top;
104       ptr->top += size;
105       return tmp;
106     }
107     ptr = ptr->next;
108   }
109   return NULL;
110 }
111
112 void clearNBlocks(void *oldaddr, void * newaddr) {
113   int count = 0;
114   objstr_t *tmp = (objstr_t *) oldaddr;
115   pthread_mutex_lock(&pflookup.lock);
116   while(((unsigned int) tmp != (unsigned int)newaddr) && (tmp != NULL)) {
117     void * begin = (void *)tmp+sizeof(objstr_t);
118     void * end = (void *)tmp+sizeof(objstr_t)+tmp->size;
119     tmp->top = (void *)tmp+sizeof(objstr_t);
120     clearPLookUpTable(begin, end);
121     //TODO only for testing purpose, remove later
122     memset(tmp->top, 0, tmp->size);
123     tmp = tmp->next;
124   }
125   pthread_mutex_unlock(&pflookup.lock);
126 }
127
128 void clearPLookUpTable(void *begin, void *end) {
129   unsigned long int tmpbegin;
130   unsigned long int tmpend;
131   tmpbegin = (unsigned long int) begin;
132   tmpend = (unsigned long int) end;
133   int i, j;
134   prehashlistnode_t *ptr = pflookup.table;
135   for(i = 0; i<pflookup.size; i++) {
136     prehashlistnode_t *curr = &ptr[i];
137     for(; curr != NULL; curr = curr->next) {
138       if(((unsigned long int)(curr->val) >= tmpbegin) && ((unsigned long int)(curr->val) < tmpend)) {
139         unsigned int oid = curr->key;
140         objheader_t *objheader;
141         if((objheader = prehashSearch(oid)) != NULL) {
142           prehashRemove(oid);
143 #ifdef CHECKTA
144         printf("%s() clearing Look up table for oid = %x\n", __func__, oid);
145 #endif
146         }
147       }
148     }
149   }
150 }
151
152 void updatePtrs() {
153   void *ptr;
154   ptr = pNodeInfo->oldptr;
155   pNodeInfo->oldptr = pNodeInfo->newptr;
156   pNodeInfo->newptr = ptr;
157 }
158
159 void *allocateNew(unsigned int size) {
160   objstr_t *tmp;
161   if((tmp = (objstr_t *) calloc(1, (sizeof(objstr_t) +size))) == NULL) {
162     printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
163     return NULL;
164   }
165   tmp->size = size;
166   tmp->top = (void *)(((unsigned int)tmp) + sizeof(objstr_t) + size);
167   //Insert newly allocated block into linked list of prefetch cache
168   tmp->next = ((objstr_t *)(pNodeInfo->newptr))->next;
169   ((objstr_t *)(pNodeInfo->newptr))->next = tmp;
170   pNodeInfo->num_old_objstr++;
171   // Update maxsize of prefetch objstr blocks 
172   if(pNodeInfo->maxsize < tmp->size)
173     pNodeInfo->maxsize = tmp->size;
174   return (void *)(((unsigned int)tmp) + sizeof(objstr_t));
175 }