alert user if allocating an SESE record fails
[IRC.git] / Robust / src / Runtime / mlp_runtime.c
1 #include "runtime.h"
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <assert.h>
6
7 #include "mem.h"
8 #include "Queue.h"
9 #include "mlp_runtime.h"
10 #include "workschedule.h"
11
12
13 /*
14 __thread struct Queue* seseCallStack;
15 __thread pthread_once_t mlpOnceObj = PTHREAD_ONCE_INIT;
16 void mlpInitOncePerThread() {
17   seseCallStack = createQueue();
18 }
19 */
20 __thread SESEcommon_p seseCaller;
21
22
23 void* mlpAllocSESErecord( int size ) {
24   void* newrec = RUNMALLOC( size );  
25   if( newrec == 0 ) {
26     printf( "mlpAllocSESErecord did not obtain memory!\n" );
27     exit( -1 );
28   }
29   return newrec;
30 }
31
32
33 void mlpFreeSESErecord( void* seseRecord ) {
34   RUNFREE( seseRecord );
35 }
36
37 AllocSite* mlpCreateAllocSiteArray(int numAllocSites){
38   int i;
39   AllocSite* newAllocSite=(AllocSite*)RUNMALLOC( sizeof( AllocSite ) * numAllocSites );
40   for(i=0; i<numAllocSites; i++){
41     newAllocSite[i].waitingQueue=createQueue();
42   }
43   return newAllocSite;
44 }
45
46 ConflictNode* mlpCreateConflictNode(int id){
47   ConflictNode* newConflictNode=(ConflictNode*)RUNMALLOC( sizeof( ConflictNode ) );
48   newConflictNode->id=id;
49   return newConflictNode;
50 }
51
52 WaitingElement* mlpCreateWaitingElement(int status, void* seseToIssue, struct Queue* queue, int id){
53   WaitingElement* newElement=(WaitingElement*)RUNMALLOC(sizeof(WaitingElement));
54   newElement->status=status;
55   newElement->seseRec=seseToIssue;
56   newElement->list=queue;
57   newElement->id=id;
58   return newElement;
59 }
60
61 struct QueueItem* addWaitingQueueElement2(AllocSite* waitingQueueArray, int numWaitingQueue, int waitingID, WaitingElement* element){
62
63   int i;
64   struct QueueItem* newItem=NULL;
65   for(i=0;i<numWaitingQueue;i++){
66     if(waitingQueueArray[i].id==waitingID){
67       newItem=addNewItemBack(waitingQueueArray[i].waitingQueue,element);
68       return newItem;
69       //printf("add new item %d into waiting queue:%d\n",((SESEcommon*)seseRec)->classID,allocID);
70     }
71   }
72   return newItem;  
73   
74 }
75
76 struct QueueItem* addWaitingQueueElement(AllocSite* allocSiteArray, int numAllocSites, long allocID, void *seseRec){
77
78   int i;
79   struct QueueItem* newItem=NULL;
80   for(i=0;i<numAllocSites;i++){
81     if(allocSiteArray[i].id==allocID){
82       newItem=addNewItemBack(allocSiteArray[i].waitingQueue,seseRec);
83       return newItem;
84       //printf("add new item %d into waiting queue:%d\n",((SESEcommon*)seseRec)->classID,allocID);
85     }
86   }
87   return newItem;
88 }
89
90 int getQueueIdx(AllocSite* allocSiteArray, int numAllocSites, long  allocID){
91
92   int i;
93   for(i=0;i<numAllocSites;i++){
94     if(allocSiteArray[i].id==allocID){
95       return i;      
96     }
97   }
98   return -1;
99 }
100
101 int isRunnable(struct Queue* waitingQueue, struct QueueItem* qItem){
102
103   if(!isEmpty(waitingQueue)){
104
105     struct QueueItem* current=getHead(waitingQueue);
106     while(current!=NULL){
107          if(current!=qItem){
108            if(isConflicted(current,qItem)){
109              return 0;
110            }
111          }else{
112            return 1;
113          }
114          current=getNextQueueItem(current);
115     }
116   }
117   return 1;
118 }
119
120 int isConflicted(struct QueueItem* prevItem, struct QueueItem* item){
121
122   WaitingElement* element=item->objectptr;
123   WaitingElement* prevElement=prevItem->objectptr;
124
125   if(prevElement->id!=element->id){
126
127     if(element->status==0){ // fine read
128     
129       if(prevElement->status==1 || prevElement->status==3){
130       
131         if(isOverlapped(prevElement->list,element->list)){
132           return 1;
133         }
134       
135       }else{
136         return 0;
137       }
138         
139     }else if(element->status==1){ // fine write
140       if(isOverlapped(prevElement->list,element->list)){
141         return 1;
142       }
143     }else if(element->status==2){// coarse read
144       
145       if(prevElement->status==1 || prevElement->status==3){
146         if(isOverlapped(prevElement->list,element->list)){
147           return 1;
148         }
149       }
150
151     }else if(element->status==3){// coarse write
152       return 1;
153     }
154
155   }
156
157   return 0;
158 }
159
160 int isOverlapped(struct Queue* prevList, struct Queue* itemList){
161
162   if(!isEmpty(prevList)){
163     struct QueueItem* queueItemA=getHead(prevList); 
164     
165     while(queueItemA!=NULL){
166       ConflictNode* nodeA=queueItemA->objectptr;
167
168       if(!isEmpty(itemList)){
169         struct QueueItem* queueItemB=getHead(itemList);
170         while(queueItemB!=NULL){
171           ConflictNode* nodeB=queueItemB->objectptr;
172           if(nodeA->id==nodeB->id){
173             return 1;
174           }
175           queueItemB=getNextQueueItem(queueItemB);
176         }
177       }
178       queueItemA=getNextQueueItem(queueItemA);      
179     }
180   }
181   return 0;
182   
183 }
184
185 int resolveWaitingQueue(struct Queue* waitingQueue,struct QueueItem* qItem){
186
187   if(!isEmpty(waitingQueue)){
188
189     SESEcommon* qCommon=qItem->objectptr;
190     
191     struct QueueItem* current=getHead(waitingQueue);
192     while(current!=NULL){
193          if(current!=qItem){
194            SESEcommon* currentCommon=current->objectptr;
195            if(hasConflicts(currentCommon->classID,qCommon->connectedList)){
196              return 0;
197            }
198          }else{
199            return 1;
200          }
201          current=getNextQueueItem(current);
202     }
203   }
204   return 1;
205 }
206
207 int hasConflicts(int classID, struct Queue* connectedList){
208   
209   if(!isEmpty(connectedList)){
210     struct QueueItem* queueItem=getHead(connectedList); 
211     
212     while(queueItem!=NULL){
213       ConflictNode* node=queueItem->objectptr;
214       if(node->id==classID){
215         return 1;
216       }
217       queueItem=getNextQueueItem(queueItem);      
218     }
219   }
220   return 0;
221 }
222
223 void addNewConflictNode(ConflictNode* node, struct Queue* connectedList){
224   
225   if(!isEmpty(connectedList)){
226     struct QueueItem* qItem=getHead(connectedList);
227     while(qItem!=NULL){
228       ConflictNode* qNode=qItem->objectptr;
229       if(qNode->id==node->id){
230         return;
231       }
232       qItem=getNextQueueItem(qItem);
233     }
234   }
235
236   addNewItem(connectedList,node);
237
238 }
239
240 int contains(struct Queue* queue, struct QueueItem* qItem){
241
242   if(!isEmpty(queue)){
243     struct QueueItem* nextQItem=getHead(queue);
244     while(nextQItem!=NULL){
245       if((nextQItem->objectptr)==qItem){
246         return 1;
247       } 
248       nextQItem=getNextQueueItem(nextQItem);
249     }
250   }
251
252   return 0;
253
254 }