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