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