+#if defined(GRAN)
+
+//@node GranSim specific options, Aux fcts, Command-line option parsing routines
+//@subsection GranSim specific options
+
+static void
+enable_GranSimLight(void) {
+
+ fprintf(stderr,"GrAnSim Light enabled (infinite number of processors; 0 communication costs)\n");
+ RtsFlags.GranFlags.Light=rtsTrue;
+ RtsFlags.GranFlags.Costs.latency =
+ RtsFlags.GranFlags.Costs.fetchtime =
+ RtsFlags.GranFlags.Costs.additional_latency =
+ RtsFlags.GranFlags.Costs.gunblocktime =
+ RtsFlags.GranFlags.Costs.lunblocktime =
+ RtsFlags.GranFlags.Costs.threadcreatetime =
+ RtsFlags.GranFlags.Costs.threadqueuetime =
+ RtsFlags.GranFlags.Costs.threadscheduletime =
+ RtsFlags.GranFlags.Costs.threaddescheduletime =
+ RtsFlags.GranFlags.Costs.threadcontextswitchtime = 0;
+
+ RtsFlags.GranFlags.Costs.mpacktime =
+ RtsFlags.GranFlags.Costs.munpacktime = 0;
+
+ RtsFlags.GranFlags.DoFairSchedule = rtsTrue;
+ RtsFlags.GranFlags.DoAsyncFetch = rtsFalse;
+ RtsFlags.GranFlags.DoAlwaysCreateThreads = rtsTrue;
+ /* FetchStrategy is irrelevant in GrAnSim-Light */
+
+ /* GrAnSim Light often creates an abundance of parallel threads,
+ each with its own stack etc. Therefore, it's in general a good
+ idea to use small stack chunks (use the -o<size> option to
+ increase it again).
+ */
+ // RtsFlags.ConcFlags.stkChunkSize = 100;
+
+ RtsFlags.GranFlags.proc = 1;
+}
+
+static void
+process_gran_option(int arg, int *rts_argc, char *rts_argv[], rtsBool *error)
+{
+ if (rts_argv[arg][1] != 'b') /* All GranSim options start with -b */
+ return;
+
+ /* or a ridiculously idealised simulator */
+ if(strcmp((rts_argv[arg]+2),"oring")==0) {
+ RtsFlags.GranFlags.Costs.latency =
+ RtsFlags.GranFlags.Costs.fetchtime =
+ RtsFlags.GranFlags.Costs.additional_latency =
+ RtsFlags.GranFlags.Costs.gunblocktime =
+ RtsFlags.GranFlags.Costs.lunblocktime =
+ RtsFlags.GranFlags.Costs.threadcreatetime =
+ RtsFlags.GranFlags.Costs.threadqueuetime =
+ RtsFlags.GranFlags.Costs.threadscheduletime =
+ RtsFlags.GranFlags.Costs.threaddescheduletime =
+ RtsFlags.GranFlags.Costs.threadcontextswitchtime = 0;
+
+ RtsFlags.GranFlags.Costs.mpacktime =
+ RtsFlags.GranFlags.Costs.munpacktime = 0;
+
+ RtsFlags.GranFlags.Costs.arith_cost =
+ RtsFlags.GranFlags.Costs.float_cost =
+ RtsFlags.GranFlags.Costs.load_cost =
+ RtsFlags.GranFlags.Costs.store_cost =
+ RtsFlags.GranFlags.Costs.branch_cost = 0;
+
+ RtsFlags.GranFlags.Costs.heapalloc_cost = 1;
+
+ /* ++RtsFlags.GranFlags.DoFairSchedule; */
+ RtsFlags.GranFlags.DoStealThreadsFirst = rtsTrue; /* -bZ */
+ RtsFlags.GranFlags.DoThreadMigration = rtsTrue; /* -bM */
+ RtsFlags.GranFlags.GranSimStats.Full = rtsTrue; /* -bP */
+ return;
+ }
+
+ /* or a somewhat idealised simulator */
+ if(strcmp((rts_argv[arg]+2),"onzo")==0) {
+ RtsFlags.GranFlags.Costs.latency =
+ RtsFlags.GranFlags.Costs.fetchtime =
+ RtsFlags.GranFlags.Costs.additional_latency =
+ RtsFlags.GranFlags.Costs.gunblocktime =
+ RtsFlags.GranFlags.Costs.lunblocktime =
+ RtsFlags.GranFlags.Costs.threadcreatetime =
+ RtsFlags.GranFlags.Costs.threadqueuetime =
+ RtsFlags.GranFlags.Costs.threadscheduletime =
+ RtsFlags.GranFlags.Costs.threaddescheduletime =
+ RtsFlags.GranFlags.Costs.threadcontextswitchtime = 0;
+
+ RtsFlags.GranFlags.Costs.mpacktime =
+ RtsFlags.GranFlags.Costs.munpacktime = 0;
+
+ RtsFlags.GranFlags.Costs.heapalloc_cost = 1;
+
+ /* RtsFlags.GranFlags.DoFairSchedule = rtsTrue; */ /* -b-R */
+ /* RtsFlags.GranFlags.DoStealThreadsFirst = rtsTrue; */ /* -b-T */
+ RtsFlags.GranFlags.DoAsyncFetch = rtsTrue; /* -bZ */
+ RtsFlags.GranFlags.DoThreadMigration = rtsTrue; /* -bM */
+ RtsFlags.GranFlags.GranSimStats.Full = rtsTrue; /* -bP */
+# if defined(GRAN_CHECK) && defined(GRAN)
+ RtsFlags.GranFlags.Debug.event_stats = rtsTrue; /* print event statistics */
+# endif
+ return;
+ }
+
+ /* Communication and task creation cost parameters */
+ switch(rts_argv[arg][2]) {
+ case '.':
+ IgnoreYields = rtsTrue; // HWL HACK
+ break;
+
+ case ':':
+ enable_GranSimLight(); /* set flags for GrAnSim-Light mode */
+ break;
+
+ case 'l':
+ if (rts_argv[arg][3] != '\0')
+ {
+ RtsFlags.GranFlags.Costs.gunblocktime =
+ RtsFlags.GranFlags.Costs.latency = decode(rts_argv[arg]+3);
+ RtsFlags.GranFlags.Costs.fetchtime = 2*RtsFlags.GranFlags.Costs.latency;
+ }
+ else
+ RtsFlags.GranFlags.Costs.latency = LATENCY;
+ break;
+
+ case 'a':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.additional_latency = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.additional_latency = ADDITIONAL_LATENCY;
+ break;
+
+ case 'm':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.mpacktime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.mpacktime = MSGPACKTIME;
+ break;
+
+ case 'x':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.mtidytime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.mtidytime = 0;
+ break;
+
+ case 'r':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.munpacktime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.munpacktime = MSGUNPACKTIME;
+ break;
+
+ case 'g':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.fetchtime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.fetchtime = FETCHTIME;
+ break;
+
+ case 'n':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.gunblocktime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.gunblocktime = GLOBALUNBLOCKTIME;
+ break;
+
+ case 'u':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.lunblocktime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.lunblocktime = LOCALUNBLOCKTIME;
+ break;
+
+ /* Thread-related metrics */
+ case 't':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.threadcreatetime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.threadcreatetime = THREADCREATETIME;
+ break;
+
+ case 'q':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.threadqueuetime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.threadqueuetime = THREADQUEUETIME;
+ break;
+
+ case 'c':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.threadscheduletime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.threadscheduletime = THREADSCHEDULETIME;
+
+ RtsFlags.GranFlags.Costs.threadcontextswitchtime = RtsFlags.GranFlags.Costs.threadscheduletime
+ + RtsFlags.GranFlags.Costs.threaddescheduletime;
+ break;
+
+ case 'd':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.threaddescheduletime = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.threaddescheduletime = THREADDESCHEDULETIME;
+
+ RtsFlags.GranFlags.Costs.threadcontextswitchtime = RtsFlags.GranFlags.Costs.threadscheduletime
+ + RtsFlags.GranFlags.Costs.threaddescheduletime;
+ break;
+
+ /* Instruction Cost Metrics */
+ case 'A':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.arith_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.arith_cost = ARITH_COST;
+ break;
+
+ case 'F':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.float_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.float_cost = FLOAT_COST;
+ break;
+
+ case 'B':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.branch_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.branch_cost = BRANCH_COST;
+ break;
+
+ case 'L':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.load_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.load_cost = LOAD_COST;
+ break;
+
+ case 'S':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.store_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.store_cost = STORE_COST;
+ break;
+
+ case 'H':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.heapalloc_cost = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.heapalloc_cost = 0;
+ break;
+
+ case 'y':
+ RtsFlags.GranFlags.DoAsyncFetch = rtsTrue;
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.FetchStrategy = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.FetchStrategy = 2;
+ if (RtsFlags.GranFlags.FetchStrategy == 0)
+ RtsFlags.GranFlags.DoAsyncFetch = rtsFalse;
+ break;
+
+ case 'K': /* sort overhead (per elem in spark list) */
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.pri_spark_overhead = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.pri_spark_overhead = PRI_SPARK_OVERHEAD;
+ fprintf(stderr,"Overhead for pri spark: %d (per elem).\n",
+ RtsFlags.GranFlags.Costs.pri_spark_overhead);
+ break;
+
+ case 'O': /* sort overhead (per elem in spark list) */
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.Costs.pri_sched_overhead = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.Costs.pri_sched_overhead = PRI_SCHED_OVERHEAD;
+ fprintf(stderr,"Overhead for pri sched: %d (per elem).\n",
+ RtsFlags.GranFlags.Costs.pri_sched_overhead);
+ break;
+
+ /* General Parameters */
+ case 'p':
+ if (rts_argv[arg][3] != '\0')
+ {
+ RtsFlags.GranFlags.proc = decode(rts_argv[arg]+3);
+ if (RtsFlags.GranFlags.proc==0) {
+ enable_GranSimLight(); /* set flags for GrAnSim-Light mode */
+ } else if (RtsFlags.GranFlags.proc > MAX_PROC ||
+ RtsFlags.GranFlags.proc < 1)
+ {
+ fprintf(stderr,"setupRtsFlags: no more than %u processors allowed\n",
+ MAX_PROC);
+ *error = rtsTrue;
+ }
+ }
+ else
+ RtsFlags.GranFlags.proc = MAX_PROC;
+ break;
+
+ case 'f':
+ RtsFlags.GranFlags.Fishing = rtsTrue;
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.maxFishes = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.maxFishes = MAX_FISHES;
+ break;
+
+ case 'w':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.GranFlags.time_slice = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.GranFlags.time_slice = GRAN_TIME_SLICE;
+ break;
+
+ case 'C':
+ RtsFlags.GranFlags.DoAlwaysCreateThreads=rtsTrue;
+ RtsFlags.GranFlags.DoThreadMigration=rtsTrue;
+ break;
+
+ case 'G':
+ fprintf(stderr,"Bulk fetching enabled.\n");
+ RtsFlags.GranFlags.DoBulkFetching=rtsTrue;
+ break;
+
+ case 'M':
+ fprintf(stderr,"Thread migration enabled.\n");
+ RtsFlags.GranFlags.DoThreadMigration=rtsTrue;
+ break;
+
+ case 'R':
+ fprintf(stderr,"Fair Scheduling enabled.\n");
+ RtsFlags.GranFlags.DoFairSchedule=rtsTrue;
+ break;
+
+ case 'I':
+ fprintf(stderr,"Priority Scheduling enabled.\n");
+ RtsFlags.GranFlags.DoPriorityScheduling=rtsTrue;
+ break;
+
+ case 'T':
+ RtsFlags.GranFlags.DoStealThreadsFirst=rtsTrue;
+ RtsFlags.GranFlags.DoThreadMigration=rtsTrue;
+ break;
+
+ case 'Z':
+ RtsFlags.GranFlags.DoAsyncFetch=rtsTrue;
+ break;
+
+/* case 'z': */
+/* RtsFlags.GranFlags.SimplifiedFetch=rtsTrue; */
+/* break; */
+
+ case 'N':
+ RtsFlags.GranFlags.PreferSparksOfLocalNodes=rtsTrue;
+ break;
+
+ case 'b':
+ RtsFlags.GranFlags.GranSimStats.Binary=rtsTrue;
+ break;
+
+ case 'P':
+ /* format is -bP<c> where <c> is one char describing kind of profile */
+ RtsFlags.GranFlags.GranSimStats.Full = rtsTrue;
+ switch(rts_argv[arg][3]) {
+ case '\0': break; // nothing special, just an ordinary profile
+ case '0': RtsFlags.GranFlags.GranSimStats.Suppressed = rtsTrue;
+ break;
+ case 'b': RtsFlags.GranFlags.GranSimStats.Binary = rtsTrue;
+ break;
+ case 's': RtsFlags.GranFlags.GranSimStats.Sparks = rtsTrue;
+ break;
+ case 'h': RtsFlags.GranFlags.GranSimStats.Heap = rtsTrue;
+ break;
+ case 'n': RtsFlags.GranFlags.GranSimStats.NewLogfile = rtsTrue;
+ break;
+ case 'g': RtsFlags.GranFlags.GranSimStats.Global = rtsTrue;
+ break;
+ default: barf("Unknown option -bP%c", rts_argv[arg][3]);
+ }
+ break;
+
+ case 's':
+ RtsFlags.GranFlags.GranSimStats.Sparks=rtsTrue;
+ break;
+
+ case 'h':
+ RtsFlags.GranFlags.GranSimStats.Heap=rtsTrue;
+ break;
+
+ case 'Y': /* syntax: -bY<n>[,<n>] n ... pos int */
+ if (rts_argv[arg][3] != '\0') {
+ char *arg0, *tmp;
+
+ arg0 = rts_argv[arg]+3;
+ if ((tmp = strstr(arg0,","))==NULL) {
+ RtsFlags.GranFlags.SparkPriority = decode(arg0);
+ fprintf(stderr,"SparkPriority: %u.\n",RtsFlags.GranFlags.SparkPriority);
+ } else {
+ *(tmp++) = '\0';
+ RtsFlags.GranFlags.SparkPriority = decode(arg0);
+ RtsFlags.GranFlags.SparkPriority2 = decode(tmp);
+ fprintf(stderr,"SparkPriority: %u.\n",
+ RtsFlags.GranFlags.SparkPriority);
+ fprintf(stderr,"SparkPriority2:%u.\n",
+ RtsFlags.GranFlags.SparkPriority2);
+ if (RtsFlags.GranFlags.SparkPriority2 <
+ RtsFlags.GranFlags.SparkPriority) {
+ fprintf(stderr,"WARNING: 2nd pri < main pri (%u<%u); 2nd pri has no effect\n",
+ RtsFlags.GranFlags.SparkPriority2,
+ RtsFlags.GranFlags.SparkPriority);
+ }
+ }
+ } else {
+ /* plain pri spark is now invoked with -bX
+ RtsFlags.GranFlags.DoPrioritySparking = 1;
+ fprintf(stderr,"PrioritySparking.\n");
+ */
+ }
+ break;
+
+ case 'Q':
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.GranFlags.ThunksToPack = decode(rts_argv[arg]+3);
+ } else {
+ RtsFlags.GranFlags.ThunksToPack = 1;
+ }
+ fprintf(stderr,"Thunks To Pack in one packet: %u.\n",
+ RtsFlags.GranFlags.ThunksToPack);
+ break;
+
+ case 'e':
+ RtsFlags.GranFlags.RandomSteal = rtsFalse;
+ fprintf(stderr,"Deterministic mode (no random stealing)\n");
+ break;
+
+ /* The following class of options contains eXperimental */
+ /* features in connection with exploiting granularity */
+ /* information. I.e. if -bY is chosen these options */
+ /* tell the RTS what to do with the supplied info --HWL */
+
+ case 'W':
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.GranFlags.packBufferSize_internal = decode(rts_argv[arg]+3);
+ } else {
+ RtsFlags.GranFlags.packBufferSize_internal = GRANSIM_DEFAULT_PACK_BUFFER_SIZE;
+ }
+ fprintf(stderr,"Size of GranSim internal pack buffer: %u.\n",
+ RtsFlags.GranFlags.packBufferSize_internal);
+ break;
+
+ case 'X':
+ switch(rts_argv[arg][3]) {
+
+ case '\0':
+ RtsFlags.GranFlags.DoPrioritySparking = 1;
+ fprintf(stderr,"Priority Sparking with Normal Priorities.\n");
+ RtsFlags.GranFlags.InversePriorities = rtsFalse;
+ RtsFlags.GranFlags.RandomPriorities = rtsFalse;
+ RtsFlags.GranFlags.IgnorePriorities = rtsFalse;
+ break;
+
+ case 'I':
+ RtsFlags.GranFlags.DoPrioritySparking = 1;
+ fprintf(stderr,"Priority Sparking with Inverse Priorities.\n");
+ RtsFlags.GranFlags.InversePriorities++;
+ break;
+
+ case 'R':
+ RtsFlags.GranFlags.DoPrioritySparking = 1;
+ fprintf(stderr,"Priority Sparking with Random Priorities.\n");
+ RtsFlags.GranFlags.RandomPriorities++;
+ break;
+
+ case 'N':
+ RtsFlags.GranFlags.DoPrioritySparking = 1;
+ fprintf(stderr,"Priority Sparking with No Priorities.\n");
+ RtsFlags.GranFlags.IgnorePriorities++;
+ break;
+
+ default:
+ bad_option( rts_argv[arg] );
+ break;
+ }
+ break;
+
+ case '-':
+ switch(rts_argv[arg][3]) {
+
+ case 'C':
+ RtsFlags.GranFlags.DoAlwaysCreateThreads=rtsFalse;
+ RtsFlags.GranFlags.DoThreadMigration=rtsFalse;
+ break;
+
+ case 'G':
+ RtsFlags.GranFlags.DoBulkFetching=rtsFalse;
+ break;
+
+ case 'M':
+ RtsFlags.GranFlags.DoThreadMigration=rtsFalse;
+ break;
+
+ case 'R':
+ RtsFlags.GranFlags.DoFairSchedule=rtsFalse;
+ break;
+
+ case 'T':
+ RtsFlags.GranFlags.DoStealThreadsFirst=rtsFalse;
+ RtsFlags.GranFlags.DoThreadMigration=rtsFalse;
+ break;
+
+ case 'Z':
+ RtsFlags.GranFlags.DoAsyncFetch=rtsFalse;
+ break;
+
+ case 'N':
+ RtsFlags.GranFlags.PreferSparksOfLocalNodes=rtsFalse;
+ break;
+
+ case 'P':
+ RtsFlags.GranFlags.GranSimStats.Suppressed=rtsTrue;
+ break;
+
+ case 's':
+ RtsFlags.GranFlags.GranSimStats.Sparks=rtsFalse;
+ break;
+
+ case 'h':
+ RtsFlags.GranFlags.GranSimStats.Heap=rtsFalse;
+ break;
+
+ case 'b':
+ RtsFlags.GranFlags.GranSimStats.Binary=rtsFalse;
+ break;
+
+ case 'X':
+ RtsFlags.GranFlags.DoPrioritySparking = rtsFalse;
+ break;
+
+ case 'Y':
+ RtsFlags.GranFlags.DoPrioritySparking = rtsFalse;
+ RtsFlags.GranFlags.SparkPriority = rtsFalse;
+ break;
+
+ case 'I':
+ RtsFlags.GranFlags.DoPriorityScheduling = rtsFalse;
+ break;
+
+ case 'e':
+ RtsFlags.GranFlags.RandomSteal = rtsFalse;
+ break;
+
+ default:
+ bad_option( rts_argv[arg] );
+ break;
+ }
+ break;
+
+# if defined(GRAN_CHECK) && defined(GRAN)
+ case 'D':
+ switch(rts_argv[arg][3]) {
+ case 'Q': /* Set pack buffer size (same as 'Q' in GUM) */
+ if (rts_argv[arg][4] != '\0') {
+ RtsFlags.GranFlags.packBufferSize = decode(rts_argv[arg]+4);
+ fprintf(stderr,"Pack buffer size: %d\n",
+ RtsFlags.GranFlags.packBufferSize);
+ } else {
+ fprintf(stderr, "setupRtsFlags: missing size of PackBuffer (for -Q)\n");
+ *error = rtsTrue;
+ }
+ break;
+
+ default:
+ if (isdigit(rts_argv[arg][3])) {/* Set all debugging options in one */
+ /* hack warning: interpret the flags as a binary number */
+ nat n = decode(rts_argv[arg]+3);
+ set_GranSim_debug_options(n);
+ } else {
+ nat i;
+ for (i=0; i<=MAX_GRAN_DEBUG_OPTION; i++)
+ if (rts_argv[arg][3] == gran_debug_opts_flags[i])
+ break;
+
+ if (i==MAX_GRAN_DEBUG_OPTION+1) {
+ fprintf(stderr, "Valid GranSim debug options are:\n");
+ help_GranSim_debug_options(MAX_GRAN_DEBUG_MASK);
+ bad_option( rts_argv[arg] );
+ } else { // flag found; now set it
+ set_GranSim_debug_options(GRAN_DEBUG_MASK(i)); // 2^i
+ }
+ }
+ break;
+
+#if 0
+ case 'e': /* event trace; also -bD1 */
+ fprintf(stderr,"DEBUG: event_trace; printing event trace.\n");
+ RtsFlags.GranFlags.Debug.event_trace = rtsTrue;
+ /* RtsFlags.GranFlags.event_trace=rtsTrue; */
+ break;
+
+ case 'E': /* event statistics; also -bD2 */
+ fprintf(stderr,"DEBUG: event_stats; printing event statistics.\n");
+ RtsFlags.GranFlags.Debug.event_stats = rtsTrue;
+ /* RtsFlags.GranFlags.Debug |= 0x20; print event statistics */
+ break;
+
+ case 'f': /* thunkStealing; also -bD4 */
+ fprintf(stderr,"DEBUG: thunkStealing; printing forwarding of FETCHNODES.\n");
+ RtsFlags.GranFlags.Debug.thunkStealing = rtsTrue;
+ /* RtsFlags.GranFlags.Debug |= 0x2; print fwd messages */
+ break;
+
+ case 'z': /* blockOnFetch; also -bD8 */
+ fprintf(stderr,"DEBUG: blockOnFetch; check for blocked on fetch.\n");
+ RtsFlags.GranFlags.Debug.blockOnFetch = rtsTrue;
+ /* RtsFlags.GranFlags.Debug |= 0x4; debug non-reschedule-on-fetch */
+ break;
+
+ case 't': /* blockOnFetch_sanity; also -bD16 */
+ fprintf(stderr,"DEBUG: blockOnFetch_sanity; check for TSO asleep on fetch.\n");
+ RtsFlags.GranFlags.Debug.blockOnFetch_sanity = rtsTrue;
+ /* RtsFlags.GranFlags.Debug |= 0x10; debug TSO asleep for fetch */
+ break;
+
+ case 'S': /* priSpark; also -bD32 */
+ fprintf(stderr,"DEBUG: priSpark; priority sparking.\n");
+ RtsFlags.GranFlags.Debug.priSpark = rtsTrue;
+ break;
+
+ case 's': /* priSched; also -bD64 */
+ fprintf(stderr,"DEBUG: priSched; priority scheduling.\n");
+ RtsFlags.GranFlags.Debug.priSched = rtsTrue;
+ break;
+
+ case 'F': /* findWork; also -bD128 */
+ fprintf(stderr,"DEBUG: findWork; searching spark-pools (local & remote), thread queues for work.\n");
+ RtsFlags.GranFlags.Debug.findWork = rtsTrue;
+ break;
+
+ case 'g': /* globalBlock; also -bD256 */
+ fprintf(stderr,"DEBUG: globalBlock; blocking on remote closures (FETCHMEs etc in GUM).\n");
+ RtsFlags.GranFlags.Debug.globalBlock = rtsTrue;
+ break;
+
+ case 'G': /* pack; also -bD512 */
+ fprintf(stderr,"DEBUG: pack; routines for (un-)packing graph structures.\n");
+ RtsFlags.GranFlags.Debug.pack = rtsTrue;
+ break;
+
+ case 'P': /* packBuffer; also -bD1024 */
+ fprintf(stderr,"DEBUG: packBuffer; routines handling pack buffer (GranSim internal!).\n");
+ RtsFlags.GranFlags.Debug.packBuffer = rtsTrue;
+ break;
+
+ case 'o': /* sortedQ; also -bD2048 */
+ fprintf(stderr,"DEBUG: sortedQ; check whether spark/thread queues are sorted.\n");
+ RtsFlags.GranFlags.Debug.sortedQ = rtsTrue;
+ break;
+
+ case 'r': /* randomSteal; also -bD4096 */
+ fprintf(stderr,"DEBUG: randomSteal; stealing sparks/threads from random PEs.\n");
+ RtsFlags.GranFlags.Debug.randomSteal = rtsTrue;
+ break;
+
+ case 'q': /* checkSparkQ; also -bD8192 */
+ fprintf(stderr,"DEBUG: checkSparkQ; check consistency of the spark queues.\n");
+ RtsFlags.GranFlags.Debug.checkSparkQ = rtsTrue;
+ break;
+
+ case ':': /* checkLight; also -bD16384 */
+ fprintf(stderr,"DEBUG: checkLight; check GranSim-Light setup.\n");
+ RtsFlags.GranFlags.Debug.checkLight = rtsTrue;
+ break;
+
+ case 'b': /* bq; also -bD32768 */
+ fprintf(stderr,"DEBUG: bq; check blocking queues\n");
+ RtsFlags.GranFlags.Debug.bq = rtsTrue;
+ break;
+
+ case 'd': /* all options turned on */
+ fprintf(stderr,"DEBUG: all options turned on.\n");
+ set_GranSim_debug_options(MAX_GRAN_DEBUG_MASK);
+ /* RtsFlags.GranFlags.Debug |= 0x40; */
+ break;
+
+/* case '\0': */
+/* RtsFlags.GranFlags.Debug = 1; */
+/* break; */
+#endif
+
+ }
+ break;
+# endif /* GRAN_CHECK */
+ default:
+ bad_option( rts_argv[arg] );
+ break;
+ }
+}
+
+/*
+ Interpret n as a binary number masking GranSim debug options and set the
+ correxponding option. See gran_debug_opts_strs for explanations of the flags.
+*/
+static void
+set_GranSim_debug_options(nat n) {
+ nat i;
+
+ for (i=0; i<=MAX_GRAN_DEBUG_OPTION; i++)
+ if ((n>>i)&1) {
+ fprintf(stderr, gran_debug_opts_strs[i]);
+ switch (i) {
+ case 0: RtsFlags.GranFlags.Debug.event_trace = rtsTrue; break;
+ case 1: RtsFlags.GranFlags.Debug.event_stats = rtsTrue; break;
+ case 2: RtsFlags.GranFlags.Debug.bq = rtsTrue; break;
+ case 3: RtsFlags.GranFlags.Debug.pack = rtsTrue; break;
+ case 4: RtsFlags.GranFlags.Debug.checkSparkQ = rtsTrue; break;
+ case 5: RtsFlags.GranFlags.Debug.thunkStealing = rtsTrue; break;
+ case 6: RtsFlags.GranFlags.Debug.randomSteal = rtsTrue; break;
+ case 7: RtsFlags.GranFlags.Debug.findWork = rtsTrue; break;
+ case 8: RtsFlags.GranFlags.Debug.unused = rtsTrue; break;
+ case 9: RtsFlags.GranFlags.Debug.pri = rtsTrue; break;
+ case 10: RtsFlags.GranFlags.Debug.checkLight = rtsTrue; break;
+ case 11: RtsFlags.GranFlags.Debug.sortedQ = rtsTrue; break;
+ case 12: RtsFlags.GranFlags.Debug.blockOnFetch = rtsTrue; break;
+ case 13: RtsFlags.GranFlags.Debug.packBuffer = rtsTrue; break;
+ case 14: RtsFlags.GranFlags.Debug.blockOnFetch_sanity = rtsTrue; break;
+ default: barf("set_GranSim_debug_options: only %d debug options expected");
+ } /* switch */
+ } /* if */
+}
+
+/*
+ Print one line explanation for each of the GranSim debug options specified
+ in the bitmask n.
+*/
+static void
+help_GranSim_debug_options(nat n) {
+ nat i;
+
+ for (i=0; i<=MAX_GRAN_DEBUG_OPTION; i++)
+ if ((n>>i)&1)
+ fprintf(stderr, gran_debug_opts_strs[i]);
+}
+
+# elif defined(PAR)
+
+static void
+process_par_option(int arg, int *rts_argc, char *rts_argv[], rtsBool *error)
+{
+
+ if (rts_argv[arg][1] != 'q') { /* All GUM options start with -q */
+ belch("Warning: GUM option does not start with -q: %s", rts_argv[arg]);
+ return;
+ }
+
+ /* Communication and task creation cost parameters */
+ switch(rts_argv[arg][2]) {
+ case 'e': /* -qe<n> ... allow <n> local sparks */
+ if (rts_argv[arg][3] != '\0') { /* otherwise, stick w/ the default */
+ RtsFlags.ParFlags.maxLocalSparks
+ = strtol(rts_argv[arg]+3, (char **) NULL, 10);
+
+ if (RtsFlags.ParFlags.maxLocalSparks <= 0) {
+ belch("setupRtsFlags: bad value for -e\n");
+ *error = rtsTrue;
+ }
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qe<n>: max %d local sparks",
+ RtsFlags.ParFlags.maxLocalSparks));
+ break;
+
+ case 't':
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.maxThreads
+ = strtol(rts_argv[arg]+3, (char **) NULL, 10);
+ } else {
+ belch("setupRtsFlags: missing size for -qt\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qt<n>: max %d threads",
+ RtsFlags.ParFlags.maxThreads));
+ break;
+
+ case 'f':
+ if (rts_argv[arg][3] != '\0')
+ RtsFlags.ParFlags.maxFishes = decode(rts_argv[arg]+3);
+ else
+ RtsFlags.ParFlags.maxFishes = MAX_FISHES;
+ break;
+ IF_PAR_DEBUG(verbose,
+ belch("-qf<n>: max %d fishes sent out at one time",
+ RtsFlags.ParFlags.maxFishes));
+ break;
+
+ case 'F':
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.fishDelay
+ = strtol(rts_argv[arg]+3, (char **) NULL, 10);
+ } else {
+ belch("setupRtsFlags: missing fish delay time for -qF\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qF<n>: fish delay time %d us",
+ RtsFlags.ParFlags.fishDelay));
+ break;
+
+ case 'O':
+ RtsFlags.ParFlags.outputDisabled = rtsTrue;
+ IF_PAR_DEBUG(verbose,
+ belch("-qO: output disabled"));
+ break;
+
+ case 'g': /* -qg<n> ... globalisation scheme */
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.globalising = decode(rts_argv[arg]+3);
+ } else {
+ belch("setupRtsFlags: missing identifier for globalisation scheme (for -qg)\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qg<n>: globalisation scheme set to %d",
+ RtsFlags.ParFlags.globalising));
+ break;
+
+ case 'h': /* -qh<n> ... max number of thunks (except root) in packet */
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.thunksToPack = decode(rts_argv[arg]+3);
+ } else {
+ belch("setupRtsFlags: missing number of thunks per packet (for -qh)\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qh<n>: thunks per packet set to %d",
+ RtsFlags.ParFlags.thunksToPack));
+ break;
+
+ case 'P': /* -qP for writing a log file */
+ //RtsFlags.ParFlags.ParStats.Full = rtsFalse;
+ /* same encoding as in GranSim after -bP */
+ switch(rts_argv[arg][3]) {
+ case '\0': RtsFlags.ParFlags.ParStats.Full = rtsTrue;
+ break; // nothing special, just an ordinary profile
+ case '0': RtsFlags.ParFlags.ParStats.Suppressed = rtsTrue;
+ RtsFlags.ParFlags.ParStats.Full = rtsFalse;
+ break;
+ case 'b': RtsFlags.ParFlags.ParStats.Binary = rtsTrue;
+ break;
+ case 's': RtsFlags.ParFlags.ParStats.Sparks = rtsTrue;
+ break;
+ //case 'h': RtsFlags.parFlags.ParStats.Heap = rtsTrue;
+ // break;
+ case 'n': RtsFlags.ParFlags.ParStats.NewLogfile = rtsTrue;
+ break;
+ case 'g':
+# if defined(PAR_TICKY)
+ RtsFlags.ParFlags.ParStats.Global = rtsTrue;
+# else
+ fprintf(stderr,"-qPg is only possible for a PAR_TICKY RTS, which this is not");
+ stg_exit(EXIT_FAILURE);
+# endif
+ break;
+ default: barf("Unknown option -qP%c", rts_argv[arg][2]);
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("(-qP) writing to log-file (RtsFlags.ParFlags.ParStats.Full=%s)",
+ (RtsFlags.ParFlags.ParStats.Full ? "rtsTrue" : "rtsFalse")));
+ break;
+
+ case 'Q': /* -qQ<n> ... set pack buffer size to <n> */
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.packBufferSize = decode(rts_argv[arg]+3);
+ } else {
+ belch("setupRtsFlags: missing size of PackBuffer (for -qQ)\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qQ<n>: pack buffer size set to %d",
+ RtsFlags.ParFlags.packBufferSize));
+ break;
+
+ case 'R':
+ RtsFlags.ParFlags.doFairScheduling = rtsTrue;
+ IF_PAR_DEBUG(verbose,
+ belch("-qR: fair-ish scheduling"));
+ break;
+
+# if defined(DEBUG)
+ case 'w':
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.wait
+ = strtol(rts_argv[arg]+3, (char **) NULL, 10);
+ } else {
+ RtsFlags.ParFlags.wait = 1000;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qw<n>: length of wait loop after synchr before reduction: %d",
+ RtsFlags.ParFlags.wait));
+ break;
+
+ case 'D': /* -qD ... all the debugging options */
+ if (isdigit(rts_argv[arg][3])) {/* Set all debugging options in one */
+ /* hack warning: interpret the flags as a binary number */
+ nat n = decode(rts_argv[arg]+3);
+ set_par_debug_options(n);
+ } else {
+ nat i;
+ for (i=0; i<=MAX_PAR_DEBUG_OPTION; i++)
+ if (rts_argv[arg][3] == par_debug_opts_flags[i])
+ break;
+
+ if (i==MAX_PAR_DEBUG_OPTION+1) {
+ fprintf(stderr, "Valid GUM debug options are:\n");
+ help_par_debug_options(MAX_PAR_DEBUG_MASK);
+ bad_option( rts_argv[arg] );
+ } else { // flag found; now set it
+ set_par_debug_options(PAR_DEBUG_MASK(i)); // 2^i
+ }
+ }
+ break;
+# endif
+ default:
+ belch("Unknown option -q%c (%d opts in total)",
+ rts_argv[arg][2], *rts_argc);
+ break;
+ } /* switch */
+}
+
+/*
+ Interpret n as a binary number masking Par debug options and set the
+ correxponding option. See par_debug_opts_strs for explanations of the flags.
+*/
+static void
+set_par_debug_options(nat n) {
+ nat i;
+
+ for (i=0; i<=MAX_PAR_DEBUG_OPTION; i++)
+ if ((n>>i)&1) {
+ fprintf(stderr, par_debug_opts_strs[i]);
+ switch (i) {
+ case 0: RtsFlags.ParFlags.Debug.verbose = rtsTrue; break;
+ case 1: RtsFlags.ParFlags.Debug.bq = rtsTrue; break;
+ case 2: RtsFlags.ParFlags.Debug.schedule = rtsTrue; break;
+ case 3: RtsFlags.ParFlags.Debug.free = rtsTrue; break;
+ case 4: RtsFlags.ParFlags.Debug.resume = rtsTrue; break;
+ case 5: RtsFlags.ParFlags.Debug.weight = rtsTrue; break;
+ case 6: RtsFlags.ParFlags.Debug.fetch = rtsTrue; break;
+ //case 7: RtsFlags.ParFlags.Debug.ack = rtsTrue; break;
+ case 7: RtsFlags.ParFlags.Debug.fish = rtsTrue; break;
+ case 8: RtsFlags.ParFlags.Debug.tables = rtsTrue; break;
+ case 9: RtsFlags.ParFlags.Debug.packet = rtsTrue; break;
+ case 10: RtsFlags.ParFlags.Debug.pack = rtsTrue; break;
+ case 11: RtsFlags.ParFlags.Debug.paranoia = rtsTrue; break;
+ default: barf("set_par_debug_options: only %d debug options expected",
+ MAX_PAR_DEBUG_OPTION);
+ } /* switch */
+ } /* if */
+}
+
+/*
+ Print one line explanation for each of the GranSim debug options specified
+ in the bitmask n.
+*/
+static void
+help_par_debug_options(nat n) {
+ nat i;
+
+ for (i=0; i<=MAX_PAR_DEBUG_OPTION; i++)
+ if ((n>>i)&1)
+ fprintf(stderr, par_debug_opts_strs[i]);
+}
+
+#endif /* PAR */
+
+//@node Aux fcts, , GranSim specific options
+//@subsection Aux fcts
+