/* -----------------------------------------------------------------------------
- * $Id: Main.c,v 1.9 1999/07/06 15:05:49 sof Exp $
+ * $Id: Main.c,v 1.18 2000/03/14 09:55:05 simonmar Exp $
*
- * (c) The GHC Team 1998-1999
+ * (c) The GHC Team 1998-2000
*
* Main function for a standalone Haskell program.
*
#include "RtsAPI.h"
#include "SchedAPI.h"
#include "RtsFlags.h"
-#include "Schedule.h" /* for MainTSO */
#include "RtsUtils.h"
+#include "Prelude.h"
#ifdef DEBUG
-#include "Printer.h" /* for printing */
+# include "Printer.h" /* for printing */
#endif
#ifdef INTERPRETER
-#include "Assembler.h"
+# include "Assembler.h"
#endif
#ifdef PAR
-#include "ParInit.h"
-#include "Parallel.h"
-#include "LLC.h"
+# include "ParInit.h"
+# include "Parallel.h"
+# include "LLC.h"
#endif
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
+#if defined(GRAN) || defined(PAR)
+# include "GranSimRts.h"
#endif
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
-#ifndef ENABLE_WIN32_DLL_SUPPORT
/* Hack: we assume that we're building a batch-mode system unless
* INTERPRETER is set
# ifndef INTERPRETER /* Hack */
int main(int argc, char *argv[])
{
+ int exit_status;
SchedulerStatus status;
+ /* all GranSim/GUM init is done in startupHaskell; sets IAmMainThread! */
+
startupHaskell(argc,argv);
-# ifndef PAR
- MainTSO = createIOThread(stg_max(BLOCK_SIZE_W,
- RtsFlags.GcFlags.initialStkSize),
- (StgClosure *)&mainIO_closure);
- status = schedule(MainTSO,NULL);
-# else
+ /* kick off the computation by creating the main thread with a pointer
+ to mainIO_closure representing the computation of the overall program;
+ then enter the scheduler with this thread and off we go;
+
+ the same for GranSim (we have only one instance of this code)
+
+ in a parallel setup, where we have many instances of this code
+ running on different PEs, we should do this only for the main PE
+ (IAmMainThread is set in startupHaskell)
+ */
+
+# if defined(PAR)
+
+# if DEBUG
+ { /* a wait loop to allow attachment of gdb to UNIX threads */
+ nat i, j, s;
+
+ for (i=0, s=0; i<(nat)RtsFlags.ParFlags.wait; i++)
+ for (j=0; j<1000000; j++)
+ s += j % 65536;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("Passed wait loop"));
+# endif
+
if (IAmMainThread == rtsTrue) {
- /*Just to show we're alive */
fprintf(stderr, "Main Thread Started ...\n");
-
- MainTSO = createIOThread(stg_max(BLOCK_SIZE_W,
- RtsFlags.GcFlags.initialStkSize),
- (StgClosure *)&mainIO_closure);
- status = schedule(MainTSO,NULL);
+
+ /* ToDo: Dump event for the main thread */
+ status = rts_evalIO(mainIO_closure, NULL);
} else {
- WaitForPEOp(PP_FINISH,SysManTask);
- exit(EXIT_SUCCESS);
+ /* Just to show we're alive */
+ IF_PAR_DEBUG(verbose,
+ fprintf(stderr, "== [%x] Non-Main PE enters scheduler without work ...\n",
+ mytid));
+
+ /* all non-main threads enter the scheduler without work */
+ status = schedule( /* nothing */ );
}
-# endif /* PAR */
+
+# elif defined(GRAN)
+
+ /* ToDo: Dump event for the main thread */
+ status = rts_evalIO(mainIO_closure, NULL);
+
+# else /* !PAR && !GRAN */
+
+ /* ToDo: want to start with a larger stack size */
+ status = rts_evalIO((StgClosure *)mainIO_closure, NULL);
+
+# endif /* !PAR && !GRAN */
+
+ // ToDo: update for parallel execution
+ /* check the status of the entire Haskell computation */
switch (status) {
- case AllBlocked:
- barf("Scheduler stopped, all threads blocked");
case Deadlock:
- shutdownHaskell();
- barf("No threads to run! Deadlock?");
+ prog_belch("no threads to run: infinite loop or deadlock?");
+ exit_status = EXIT_DEADLOCK;
+ break;
case Killed:
- belch("%s: warning: main thread killed", prog_argv[0]);
- case Success:
+ prog_belch("main thread killed");
+ exit_status = EXIT_KILLED;
+ break;
case Interrupted:
- /* carry on */
+ prog_belch("interrupted");
+ exit_status = EXIT_INTERRUPTED;
+ break;
+ case Success:
+ exit_status = EXIT_SUCCESS;
+ break;
+ default:
+ barf("main thread completed with invalid status");
}
- shutdownHaskell();
- stg_exit(EXIT_SUCCESS);
+ shutdownHaskellAndExit(exit_status);
}
# endif /* BATCH_MODE */
-
-#else /* !ENABLE_WIN32_DLL_SUPPORT */
-
-static char* args[] = { "ghcRts" };
-
-BOOL
-WINAPI
-DllMain ( HINSTANCE hInstance
- , DWORD reason
- , LPVOID reserved
- )
-{
- /*
- ToDo: let the user configure RTS options to use
- via the registry.
- */
- switch (reason) {
- case DLL_PROCESS_ATTACH:
- startupHaskell(1,args);
- /* ToDo: gracefully handle startupHaskell() failures.. */
- return TRUE;
- case DLL_PROCESS_DETACH:
- shutdownHaskell();
- }
- return TRUE;
-}
-
-#endif /* !ENABLE_WIN32_DLL_SUPPORT */