6b1ec5f9440b4efff1a0b356a565e2a7ee0e0aa2
[ghc-hetmet.git] / ghc / runtime / storage / SMinit.lc
1 \section[storage-manager-init]{Initialising the storage manager}
2
3 To initialise the storage manager, we pass it:
4 \begin{itemize}
5 \item
6 An @argc@/@argv@ combo, which are the command-line arguments that have
7 been deemed to belong to the runtime system.  The initialisation
8 routine can slurp around in there for information of interest to
9 it.
10
11 \item
12 A filehandle to which any storage-manager statistics should be written.
13 \end{itemize}
14
15 \begin{code}
16 #define NULL_REG_MAP
17 #include "SMinternal.h"
18
19 /* global vars to hold some storage-mgr details; */
20 /* decls for these are in SMinternal.h           */
21 I_   SM_force_gc       = 0;
22 I_   SM_alloc_size     = 0;
23 I_   SM_alloc_min      = 0;
24 I_   SM_major_gen_size = 0;
25 FILE *SM_statsfile = NULL;
26 I_   SM_trace = 0;
27 I_   SM_stats_summary = 0;
28 I_   SM_stats_verbose = 0;
29 I_   SM_ring_bell = 0;
30
31 /*To SizeHooks: I_   SM_word_heap_size = DEFAULT_HEAP_SIZE; */
32 /*To SizeHooks: StgFloat SM_pc_free_heap = DEFAULT_PC_FREE; */
33 extern I_ SM_word_stk_size; /*To SizeHooks: = DEFAULT_STACKS_SIZE; */
34
35 I_ MaxResidency = 0;     /* in words; for stats only */
36 I_ ResidencySamples = 0; /* for stats only */
37
38 #ifndef atof
39 extern double atof();
40 /* no proto because some machines use const and some do not */
41 #endif
42
43 I_
44 decode(s)
45   char *s;
46 {
47     I_ c;
48     StgDouble m;
49     if (!*s)
50         return 0;
51     m = atof(s);
52     c = s[strlen(s)-1];
53     if (c == 'g' || c == 'G')
54         m *= 1000*1000*1000;    /* UNchecked! */
55     else if (c == 'm' || c == 'M')
56         m *= 1000*1000;                 /* We do not use powers of 2 (1024) */
57     else if (c == 'k' || c == 'K')      /* to avoid possible bad effects on */
58         m *= 1000;                      /* a direct-mapped cache.           */ 
59     else if (c == 'w' || c == 'W')
60         m *= sizeof(W_);
61     return (I_)m;
62 }
63
64 static void
65 badoption(s)
66   char *s;
67 {
68   fflush(stdout);
69   fprintf(stderr, "initSM: Bad RTS option: %s\n", s);
70   EXIT(EXIT_FAILURE);
71 }               
72
73 extern long strtol  PROTO((const char *, char **, int)); /* ToDo: properly? */
74
75 I_
76 initSM(rts_argc, rts_argv, statsfile)
77     I_     rts_argc;
78     char **rts_argv;
79     FILE  *statsfile;
80 {
81     I_ arg;
82
83     /* save statsfile info */
84     SM_statsfile = statsfile;
85     
86     /* slurp through RTS args */
87
88     for (arg = 0; arg < rts_argc; arg++) {
89         if (rts_argv[arg][0] == '-') {
90             switch(rts_argv[arg][1]) {
91               case 'H':
92                 SM_word_heap_size = decode(rts_argv[arg]+2) / sizeof(W_);
93
94                 if (SM_word_heap_size <= 0) badoption( rts_argv[arg] );
95                 break;
96
97               case 'M':
98                 SM_pc_free_heap = atof(rts_argv[arg]+2);
99
100                 if ((SM_pc_free_heap < 0) || (SM_pc_free_heap > 100))
101                     badoption( rts_argv[arg] );
102                 break;
103
104               case 'A':
105                 SM_alloc_size = decode(rts_argv[arg]+2) / sizeof(W_);
106
107                 if (SM_alloc_size == 0) SM_alloc_size = DEFAULT_ALLOC_SIZE;
108                 break;
109
110               case 'G':
111                 SM_major_gen_size = decode(rts_argv[arg]+2) / sizeof(W_);
112                 break;
113
114               case 'F':
115                 if (strcmp(rts_argv[arg]+2, "2s") == 0) {
116                     SM_force_gc = USE_2s;
117                 } else if (strcmp(rts_argv[arg]+2, "1s") == 0) {
118                     badoption( rts_argv[arg] ); /* ToDo ! */
119                 } else {
120                     badoption( rts_argv[arg] );
121                 }
122                 break;
123
124               case 'K':
125                 SM_word_stk_size = decode(rts_argv[arg]+2) / sizeof(W_);
126
127                 if (SM_word_stk_size == 0) badoption( rts_argv[arg] );
128                 break;
129
130               case 'S':
131                 SM_stats_verbose++;
132                 /* statsfile has already been determined */
133                 break;
134               case 's':
135                 SM_stats_summary++;
136                 /* statsfile has already been determined */
137                 break;
138               case 'B':
139                 SM_ring_bell++;
140                 break;
141
142               case 'T':
143                 if (rts_argv[arg][2] != '\0')
144                     SM_trace = (I_) strtol(rts_argv[arg]+2, (char **)NULL, 0);
145                 else
146                     SM_trace = 1;
147                 break;
148
149 #ifdef GCdu
150               case 'u':
151                 dualmodeInfo.resid_to_compact = atof(rts_argv[arg]+2);
152                 dualmodeInfo.resid_from_compact = dualmodeInfo.resid_from_compact + 0.05;
153                 if (dualmodeInfo.resid_from_compact < 0.0 ||
154                     dualmodeInfo.resid_to_compact > 1.0) {
155                   badoption( rts_argv[arg] );
156                 }
157 #endif
158
159               default:
160                 /* otherwise none of my business */
161                 break;
162             }
163         }
164         /* else none of my business */
165     }
166
167     SM_alloc_min = (I_) (SM_word_heap_size * SM_pc_free_heap / 100);
168
169     return(0); /* all's well */
170 }
171 \end{code}
172
173
174 \section[storage-manager-exit]{Winding up the storage manager}
175
176 \begin{code}
177
178 I_
179 exitSM (sm_info)
180     smInfo *sm_info;
181 {
182     stat_exit(sm_info->hp - hp_start);
183
184     return(0); /* I'm happy */
185 }
186 \end{code}