1 %****************************************************************************
3 \section[Sysman.lc]{GUM Sysman Program}
5 % (c) The Parade/AQUA Projects, Glasgow University, 1994-1995.
6 % P. Trinder, November 30th. 1994.
8 %****************************************************************************
10 The Sysman task controls initiation, termination, global GC
11 synchronisation and statistics gathering. Based on K. Hammond's SysMan.lc
15 #define NON_POSIX_SOURCE /* so says Solaris */
22 static GLOBAL_TASK_ID gtids[MAX_PES], StatsTask = 0;
23 static long PEbuffer[MAX_PES];
28 static GLOBAL_TASK_ID sysman_id, sender_id, mainThread_id;
32 static unsigned PEsTerminated = 0;
34 static rtsBool Finishing = rtsFalse;
38 #define checkerr(c) do {if((c)<0) { pvm_perror("Sysman"); EXIT(EXIT_FAILURE); }} while(0)
41 This Function not yet implemented for GUM
45 DoGlobalGC(STG_NO_ARGS)
49 HandleException(STG_NO_ARGS)
55 main(int argc, char **argv)
61 int spawn_flag = PvmTaskDefault;
63 char *petask, *pvmExecutable;
69 if (*argv[1] == '-') {
70 spawn_flag = PvmTaskDebug;
74 mainThread_id = pvm_mytid();/* This must be the first PVM call */
75 checkerr(mainThread_id);
79 if ((petask = getenv(PETASK)) == NULL)
83 fprintf(stderr, "nPEs (%s) = %d\n", petask, nPEs);
86 /* Check that we can create the number of PE and IMU tasks requested */
88 fprintf(stderr, "No more than %d PEs allowed (%d requested)\n", MAX_PES, nPEs);
92 Get the full path and filename of the pvm executable (stashed in some
95 pvmExecutable = argv[2];
97 /* Create the PE Tasks */
99 /* Spawn nPEs-1 pvm threads: the Main Thread (starts execution and performs
100 IO is created by forking SysMan */
103 fprintf(stderr, "Spawning %d PEs(%s) ...\n", nPEs, petask);
104 fprintf(stderr, " args: ");
105 for (i = 0; pargv[i]; ++i)
106 fprintf(stderr, "%s, ", pargv[i]);
107 fprintf(stderr, "\n");
109 /* Initialise the PE task arguments from Sysman's arguments */
111 checkerr(pvm_spawn(petask, pargv, spawn_flag, "", nPEs, gtids));
112 PEbuffer[0] = mainThread_id;
113 for (i = 0; i < nPEs; i++)
114 PEbuffer[i++] = (long) gtids[i];
116 fprintf(stderr, "Spawned /* PWT */\n");
121 SysMan joins PECTLGROUP, so that it can wait (at the
122 barrier sysnchronisation a few instructions later) for the
123 other PE-tasks to start.
125 Other comments on PVM groupery:
127 The manager group (MGRGROUP) is vestigial at the moment. It
128 may eventually include a statistics manager, garbage
131 I suspect that you're [Kei Davis] right: Sysman shouldn't
132 be in PEGROUP, it's a hangover from GRIP.
134 (Phil Trinder, 95/10)
136 checkerr(pvm_joingroup(PECTLGROUP));
138 fprintf(stderr, "Joined PECTLGROUP /* PWT */\n");
141 /* Wait for all the PEs and IMUs to arrive */
142 checkerr(pvm_barrier(PECTLGROUP, nPEs + 1));
145 fprintf(stderr, "PECTLGROUP barrier passed /* HWL */\n");
148 Create the MainThread PE by forking SysMan. This arcane coding
149 is required to allow MainThread to read stdin and write to stdout.
154 exec($some path$/petask) /* Parent task become Main Thread PE */
156 /* Child continues as SysMan */
157 pvmendtask(); /* Disconnect from PVM to avoid confusion */
158 sysman_id = pvm_mytid(); /* Reconnect to PVM to get new task id */
160 /* Broadcast Global Task Ids of all PEs */
162 pvm_initsend(PvmDataDefault);
163 PutArgs(PEbuffer, nPEs);
164 pvm_bcast(PEGROUP, PP_PETIDS);
167 fprintf(stderr, "Main Thread Task is [t%x]\n", mainThread_id);
170 pvm_initsend(PvmDataDefault);
171 pvm_send(mainThread_id, PP_IO_INIT);
173 pvm_initsend(PvmDataDefault);
174 pvm_bcast(PEGROUP, PP_INIT);
176 fprintf(stderr, "Broadcast PP_INIT to all PEs\n");
181 fprintf(stderr, "Sysman successfully initialized!\n");
184 /* Process incoming messages */
186 if ((rbufid = pvm_recv(ANY_TASK, ANY_OPCODE)) < 0)
187 pvm_perror("Sysman: Receiving Message");
190 pvm_bufinfo(rbufid, &nbytes, &opcode, &sender_id);
193 fprintf(stderr, "HWL-DBG(SysMan; main loop): rbufid=%x, nbytes = %d, opcode = %x, sender_id = %x\n",
194 rbufid, nbytes, opcode, sender_id);
199 /* This Function not yet implemented for GUM */
200 fprintf(stderr, "Global GC from %x Not yet implemented for GUM!\n", sender_id);
201 sync(PECTLGROUP, PP_FULL_SYSTEM);
202 broadcast(PEGROUP, PP_GC_INIT);
204 broadcast(PEGROUP, PP_INIT);
209 /* This Function not yet implemented for GUM */
213 fprintf(stderr, "Finish from %x\n", sender_id);
215 long buf = (long) StatsTask;
217 pvm_initsend(PvmDataDefault);
218 pvm_pklong(&buf, 1, 1);
219 pvm_bcast(PEGROUP, PP_FINISH);
224 if (PEsTerminated >= nPEs) {
225 broadcast(PEGROUP, PP_FINISH);
226 broadcast(MGRGROUP, PP_FINISH);
227 pvm_lvgroup(PEGROUP);
228 pvm_lvgroup(PECTLGROUP);
229 pvm_lvgroup(MGRGROUP);
236 fprintf(stderr, "Fail from %x\n", sender_id);
239 broadcast(PEGROUP, PP_FAIL);
245 /* char *opname = GetOpName(opcode);
246 fprintf(stderr,"Sysman: Unrecognised opcode %s (%x)\n",
248 fprintf(stderr, "Sysman: Unrecognised opcode (%x)\n",
260 @myexit@ for the system manager.