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