*** empty log message ***
[charm.git] / src / arch / sim / machine.c
1 /***************************************************************************
2  * RCS INFORMATION:
3  *
4  *      $RCSfile$
5  *      $Author$        $Locker$                $State$
6  *      $Revision$      $Date$
7  *
8  ***************************************************************************
9  * DESCRIPTION:
10  *
11  ***************************************************************************
12  * REVISION HISTORY:
13  *
14  * $Log$
15  * Revision 1.13  1997-08-04 09:50:40  jyelon
16  * *** empty log message ***
17  *
18  * Revision 1.12  1997/03/24 16:21:54  milind
19  * removed an alignment bug caused by mycpy. Replaced mycpy with memcpy.
20  *
21  * Revision 1.11  1997/03/19 04:31:30  jyelon
22  * Redesigned ConverseInit
23  *
24  * Revision 1.10  1996/07/24 21:42:32  gursoy
25  * fixed CmiTimer superinstall problems
26  *
27  * Revision 1.9  1996/07/15  20:59:22  jyelon
28  * Moved much timer, signal, etc code into common.
29  *
30  * Revision 1.8  1995/11/08 23:40:58  gursoy
31  * fixed varsize msg related bug
32  *
33  * Revision 1.7  1995/11/08  00:42:13  jyelon
34  * *** empty log message ***
35  *
36  * Revision 1.6  1995/11/08  00:40:20  jyelon
37  * *** empty log message ***
38  *
39  * Revision 1.5  1995/11/07  23:22:56  jyelon
40  * Fixed the neighbour functions.
41  *
42  * Revision 1.4  1995/10/27  21:45:35  jyelon
43  * Changed CmiNumPe --> CmiNumPes
44  *
45  * Revision 1.3  1995/10/13  22:05:59  gursoy
46  * put CmiGrabBuffer init stuff
47  *
48  * Revision 1.2  1995/10/13  20:05:13  jyelon
49  * *** empty log message ***
50  *
51  * Revision 1.1  1995/10/13  16:08:54  gursoy
52  * Initial revision
53  *
54  ***************************************************************************/
55 static char ident[] = "@(#)$Header$";
56
57 #include <stdio.h>
58 #include <math.h>
59 #include "machine.h"
60 #include "converse.h"
61
62 #ifdef CMK_TIMER_SIM_USE_TIMES
63 #include <sys/times.h>
64 #include <sys/unistd.h>
65 #endif
66 #ifdef CMK_TIMER_SIM_USE_GETRUSAGE
67 #include <sys/time.h>
68 #include <sys/resource.h>
69 #endif
70
71
72
73 static void **McQueue;
74
75 int Cmi_mype;
76 int Cmi_numpes;
77
78
79 CsvDeclare(int, CsdStopCount);
80 CpvDeclare(void*, CmiLocalQueue);
81 CpvExtern(int, CcdNumChecks);
82 CpvExtern(int, disable_sys_msgs);
83
84 double CmiTimer();
85
86 static void CsiTimerInit();
87 static double CsiTimer();
88
89
90 CpvStaticDeclare(int,CmiBufferGrabbed);
91
92
93 void CmiDeliversInit()
94 {
95   CpvInitialize(int, CmiBufferGrabbed);
96   CpvAccess(CmiBufferGrabbed) = 0;
97 }
98
99
100 void CmiGrabBuffer()
101 {
102   CpvAccess(CmiBufferGrabbed) = 1;
103 }
104
105
106 int CmiDeliverMsgs(maxmsgs)
107 int maxmsgs;
108 {
109      return maxmsgs;
110 }
111
112 void CmiDeliverSpecificMsg(handler)
113 int handler;
114 {
115 }
116
117 CmiUniContextSwitch(i)
118 int i;
119 {
120      Cmi_mype = i; 
121 }
122
123 void CmiNotifyIdle()
124 {
125 #if CMK_WHEN_PROCESSOR_IDLE_USLEEP
126   struct timeval tv;
127   tv.tv_sec=0; tv.tv_usec=5000;
128   select(0,0,0,0,&tv);
129 #endif
130 }
131
132 void *CmiAlloc(size)
133 int size;
134 {
135 char *res;
136 res =(char *)malloc(size+8);
137 if (res==0) printf("Memory allocation failed.");
138 ((int *)res)[0]=size;
139 return (void *)(res+8);
140 }
141
142 int CmiSize(blk)
143 void *blk;
144 {
145 return ((int *)( ((char *)blk)-8))[0];
146 }
147
148 void CmiFree(blk)
149 void *blk;
150 {
151 free( ((char *)blk)-8);
152 }
153
154
155
156
157 /********************* MESSAGE SEND FUNCTIONS ******************/
158
159 void CmiSyncSendFn(destPE, size, msg)
160 int destPE;
161 int size;
162 char * msg;
163 {
164     char *buf;
165
166     buf              =  (char *)malloc(size+8);
167     ((int *)buf)[0]  =  size;
168     buf += 8;
169     memcpy(buf,msg,size);
170
171     sim_send_message(Cmi_mype,buf,size,FALSE,destPE);
172 }
173
174
175
176
177 CmiCommHandle CmiAsyncSendFn(destPE, size, msg)
178 int destPE;
179 int size;
180 char * msg;
181 {
182      CmiSyncSendFn(destPE, size, msg);
183      return 0;
184 }
185
186
187
188 void CmiFreeSendFn(destPE, size, msg)
189 int destPE;
190 int size;
191 char * msg;
192 {
193      sim_send_message(Cmi_mype,msg,size,FALSE,destPE);
194 }
195
196
197
198 int CmiAsyncMsgSent(c)
199 CmiCommHandle c ;
200 {
201     return 1;
202 }
203
204
205 void CmiReleaseCommHandle(c)
206 CmiCommHandle c ;
207 {
208 }
209
210
211 void CmiNodeBarrier()
212 {
213 }
214
215
216 /********************* MESSAGE RECEIVE FUNCTIONS ******************/
217
218 void *CmiGetNonLocal(){return NULL;}
219
220
221
222
223 /*********************** BROADCAST FUNCTIONS **********************/
224
225
226 void CmiFreeBroadcastAllFn(size, msg)
227 int size;
228 char * msg;
229 {
230     int i;
231     for(i=0; i<Cmi_numpes; i++)
232        if (i!= Cmi_mype) CmiSyncSendFn(i,size,msg);
233          
234     FIFO_EnQueue(CpvAccess(CmiLocalQueue),msg);
235 }
236
237
238 void CmiSyncBroadcastFn(size, msg)      /* ALL_EXCEPT_ME  */
239 int size;
240 char * msg;
241 {
242     int i;
243     for(i=0; i<Cmi_numpes; i++)
244        if (i!= Cmi_mype) CmiSyncSendFn(i,size,msg);
245 }
246
247
248 void CmiSyncBroadcastAllFn(size, msg)
249 int size;
250 char * msg;
251 {
252      int i;
253
254      char *buf;
255
256      for(i=0; i<Cmi_numpes; i++)
257         if (i!= Cmi_mype) CmiSyncSendFn(i,size,msg);
258
259      buf              =  (char *)malloc(size+8);
260      ((int *)buf)[0]  =  size; 
261      buf += 8;
262      memcpy(buf,msg,size);
263      FIFO_EnQueue(CpvAccess(CmiLocalQueue),buf);
264 }
265
266
267
268 void CmiFreeBroadcastFn(size, msg)      /* ALL_EXCEPT_ME  */
269 int size;
270 char * msg;
271 {
272     CmiSyncBroadcastFn(size, msg);
273     CmiFree(msg);
274 }
275
276
277
278
279
280 CmiCommHandle CmiAsyncBroadcastFn(size, msg)    /* ALL_EXCEPT_ME  */
281 int size;
282 char * msg;
283 {
284         CmiSyncBroadcastFn(size, msg); 
285         return 0 ;
286 }
287
288
289
290
291 CmiCommHandle CmiAsyncBroadcastAllFn(size, msg)
292 int size;
293 char * msg;
294 {
295         CmiSyncBroadcastAll(size,msg);
296         return 0 ;
297 }
298
299
300
301
302 /**********************  LOAD BALANCER NEEDS **********************/
303
304 long CmiNumNeighbours(node)
305 int node;
306 {
307   int bit, count=0;
308   bit = 1;
309   while (1) {
310     int neighbour = node ^ bit;
311     if (neighbour < Cmi_numpes) count++;
312     bit<<1; if (bit > Cmi_numpes) break;
313   }
314   return count;
315 }
316
317 int CmiGetNodeNeighbours(node, neighbours)
318 int node, *neighbours;
319 {
320   int bit, count=0;
321   bit = 1;
322   while (1) {
323     int neighbour = node ^ bit;
324     if (neighbour < Cmi_numpes) neighbours[count++] = neighbour;
325     bit<<1; if (bit > Cmi_numpes) break;
326   }
327   return count;
328 }
329  
330 int CmiNeighboursIndex(node, nbr)
331 int node, nbr;
332 {
333   int bit, count=0;
334   bit = 1;
335   while (1) {
336     int neighbour = node ^ bit;
337     if (neighbour < Cmi_numpes) { if (nbr==neighbour) return count; count++; }
338     bit<<=1; if (bit > Cmi_numpes) break;
339   }
340   return(-1);
341 }
342
343
344 /************************** SETUP ***********************************/
345
346 void ConverseInit(int argc, char **argv, CmiStartFn fn, int usc, int initret)
347 {
348   char *argvec[1000];
349   void simulate();
350   int i, requested_npe;
351   
352   if ((usc)||(initret)) {
353     fprintf(stderr,"ConverseInit in SIM version is limited:\n");
354     fprintf(stderr," 1. User-Calls-Scheduler mode is not supported.\n");
355     fprintf(stderr," 2. ConverseInit-Returns mode is not supported.\n");
356     exit(1);
357   }
358   
359   CthInit(argv);
360   
361   /* figure out number of processors required */
362   
363   i = 0; requested_npe = 0;
364   while (argv[i] != NULL) {
365     if (strcmp(argv[i], "+p") == 0) {
366       requested_npe = atoi(argv[i+1]);
367       break;
368     } else if (strncmp(argv[i], "+p", 2)==0) {
369       requested_npe = atoi(argv[i]+2);
370       break;
371     }
372     i++;
373   }
374
375   if (requested_npe <= 0) {
376     printf("Error: requested number of processors is invalid %d\n",
377            requested_npe);
378     exit(1);
379   }
380
381   Cmi_numpes = requested_npe;
382   Cmi_mype   = 0;
383
384   McQueue = (void **) malloc(requested_npe * sizeof(void *)); 
385   for(i=0; i<requested_npe; i++) McQueue[i] = (void *) FIFO_Create();
386   sim_initialize("sim.param",requested_npe);
387   
388   CsiTimerInit();
389   for(i=0; i<CmiNumPes(); i++) {
390     CmiUniContextSwitch(i);
391     CpvInitialize(void*, CmiLocalQueue);
392     CpvAccess(CmiLocalQueue) = (void *) FIFO_Create();
393     ConverseCommonInit(argv);
394     memcpy(argvec, argv, argc*sizeof(char*));
395     fn(argc, argvec);
396     CpvAccess(CsdStopFlag) = 0;
397   }
398   
399   CsvAccess(CsdStopCount) = CmiNumPes();
400   CmiUniContextSwitch(0);
401
402   while (CsvAccess(CsdStopCount)) simulate();
403
404   exit(0);
405 }
406
407 void CsdExitScheduler()
408 {
409   CpvAccess(CsdStopFlag) = 1;
410   CsvAccess(CsdStopCount)--;
411 }
412
413
414
415 /* ********************************************************************* */
416 /*                      SIMULATOR                                        */
417 /* ********************************************************************* */
418
419
420
421 #if CMK_TIMER_SIM_USE_TIMES
422
423 static struct tms inittime;
424
425 static void CsiTimerInit()
426 {
427   times(&inittime);
428 }
429
430 static double CsiTimer()
431 {
432   double currenttime;
433   int clk_tck;
434     struct tms temp;
435
436     times(&temp);
437     clk_tck=sysconf(_SC_CLK_TCK);
438     currenttime =
439      (((temp.tms_utime - inittime.tms_utime)+
440        (temp.tms_stime - inittime.tms_stime))*1.0)/clk_tck;
441     return (currenttime);
442 }
443
444 #endif
445
446 #if CMK_TIMER_SIM_USE_GETRUSAGE
447
448 static struct rusage inittime;
449
450 static void CsiTimerInit()
451 {
452   getrusage(0, &inittime);
453 }
454
455
456 static double CsiTimer() {
457   double currenttime;
458
459   struct rusage temp;
460   getrusage(0, &temp);
461   currenttime =
462     (temp.ru_utime.tv_usec - inittime.ru_utime.tv_usec) * 0.000001+
463       (temp.ru_utime.tv_sec - inittime.ru_utime.tv_sec) +
464         (temp.ru_stime.tv_usec - inittime.ru_stime.tv_usec) * 0.000001+
465           (temp.ru_stime.tv_sec - inittime.ru_stime.tv_sec) ;
466
467   return (currenttime);
468 }
469
470 #endif
471
472
473
474 static double Csi_global_time;
475 static double Csi_start_time;
476
477
478
479 double CmiTimer()
480 {
481   return (CsiTimer() - Csi_start_time  + Csi_global_time);
482 }
483
484 double CmiWallTimer()
485 {
486   return (CsiTimer() - Csi_start_time  + Csi_global_time);
487 }
488
489 double CmiCpuTimer()
490 {
491   return (CsiTimer() - Csi_start_time  + Csi_global_time);
492 }
493
494 #include "ext_func.h"
495 #include "sim.c"
496 #include "heap.c"
497 #include "net.c"
498 #include "simqmng.c"
499 #include "simrand.c"