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