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