1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 1998-2004
5 * General utility functions used in the RTS.
7 * ---------------------------------------------------------------------------*/
9 #include "PosixSource.h"
25 #ifdef HAVE_GETTIMEOFDAY
38 #if defined(THREADED_RTS) && defined(openbsd_HOST_OS) && defined(HAVE_PTHREAD_H)
47 /* -----------------------------------------------------------------------------
48 Result-checking malloc wrappers.
49 -------------------------------------------------------------------------- */
52 stgMallocBytes (int n, char *msg)
56 if ((space = (char *) malloc((size_t) n)) == NULL) {
57 /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
58 MallocFailHook((W_) n, msg); /*msg*/
59 stg_exit(EXIT_INTERNAL_ERROR);
65 stgReallocBytes (void *p, int n, char *msg)
69 if ((space = (char *) realloc(p, (size_t) n)) == NULL) {
70 /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
71 MallocFailHook((W_) n, msg); /*msg*/
72 stg_exit(EXIT_INTERNAL_ERROR);
78 stgCallocBytes (int n, int m, char *msg)
82 if ((space = (char *) calloc((size_t) n, (size_t) m)) == NULL) {
83 /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
84 MallocFailHook((W_) n*m, msg); /*msg*/
85 stg_exit(EXIT_INTERNAL_ERROR);
90 /* To simplify changing the underlying allocator used
91 * by stgMallocBytes(), provide stgFree() as well.
99 /* -----------------------------------------------------------------------------
102 Not sure if this belongs here.
103 -------------------------------------------------------------------------- */
108 StackOverflowHook(RtsFlags.GcFlags.maxStkSize * sizeof(W_));
110 #if defined(TICKY_TICKY)
111 if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
118 /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
119 OutOfHeapHook(0/*unknown request size*/,
120 RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);
122 #if defined(TICKY_TICKY)
123 if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
126 stg_exit(EXIT_HEAPOVERFLOW);
129 /* -----------------------------------------------------------------------------
132 Used in addr2Integer because the C compiler on x86 chokes on
133 strlen, trying to inline it with not enough registers available.
134 -------------------------------------------------------------------------- */
136 nat stg_strlen(char *s)
145 /* -----------------------------------------------------------------------------
146 genSym stuff, used by GHC itself for its splitting unique supply.
148 ToDo: put this somewhere sensible.
149 ------------------------------------------------------------------------- */
151 static I_ __GenSymCounter = 0;
156 return(__GenSymCounter++);
159 resetGenSymZh(void) /* it's your funeral */
162 return(__GenSymCounter);
165 /* -----------------------------------------------------------------------------
166 Get the current time as a string. Used in profiling reports.
167 -------------------------------------------------------------------------- */
169 #if defined(PROFILING) || defined(DEBUG) || defined(PAR) || defined(GRAN)
173 static time_t now = 0;
174 static char nowstr[26];
179 ctime_r(&now, nowstr);
181 strcpy(nowstr, ctime(&now));
183 memmove(nowstr+16,nowstr+19,7);
184 nowstr[21] = '\0'; // removes the \n
190 /* -----------------------------------------------------------------------------
191 * Reset a file handle to blocking mode. We do this for the standard
192 * file descriptors before exiting, because the shell doesn't always
194 * -------------------------------------------------------------------------- */
196 #if !defined(mingw32_HOST_OS)
198 resetNonBlockingFd(int fd)
202 /* clear the non-blocking flag on this file descriptor */
203 fd_flags = fcntl(fd, F_GETFL);
204 if (fd_flags & O_NONBLOCK) {
205 fcntl(fd, F_SETFL, fd_flags & ~O_NONBLOCK);
210 setNonBlockingFd(int fd)
214 /* clear the non-blocking flag on this file descriptor */
215 fd_flags = fcntl(fd, F_GETFL);
216 if (!(fd_flags & O_NONBLOCK)) {
217 fcntl(fd, F_SETFL, fd_flags | O_NONBLOCK);
221 /* Stub defns -- async / non-blocking IO is not done
222 * via O_NONBLOCK and select() under Win32.
224 void resetNonBlockingFd(int fd STG_UNUSED) {}
225 void setNonBlockingFd(int fd STG_UNUSED) {}
229 static ullong startTime = 0;
231 /* used in a parallel setup */
235 # if defined(HAVE_GETCLOCK) && !defined(alpha_HOST_ARCH) && !defined(hppa1_1_HOST_ARCH)
238 if (getclock(TIMEOFDAY, &tv) != 0) {
240 fprintf(stderr, "Clock failed\n");
241 stg_exit(EXIT_FAILURE);
243 return tv.tv_sec * LL(1000) + tv.tv_nsec / LL(1000000) - startTime;
244 # elif HAVE_GETTIMEOFDAY && !defined(alpha_HOST_ARCH)
247 if (gettimeofday(&tv, NULL) != 0) {
249 fprintf(stderr, "Clock failed\n");
250 stg_exit(EXIT_FAILURE);
252 return tv.tv_sec * LL(1000) + tv.tv_usec / LL(1000) - startTime;
255 if ((t = time(NULL)) == (time_t) -1) {
257 fprintf(stderr, "Clock failed\n");
258 stg_exit(EXIT_FAILURE);
260 return t * LL(1000) - startTime;
265 /* -----------------------------------------------------------------------------
266 Print large numbers, with punctuation.
267 -------------------------------------------------------------------------- */
270 ullong_format_string(ullong x, char *s, rtsBool with_commas)
272 if (x < (ullong)1000)
273 sprintf(s, "%lu", (lnat)x);
274 else if (x < (ullong)1000000)
275 sprintf(s, (with_commas) ? "%lu,%3.3lu" : "%lu%3.3lu",
276 (lnat)((x)/(ullong)1000),
277 (lnat)((x)%(ullong)1000));
278 else if (x < (ullong)1000000000)
279 sprintf(s, (with_commas) ? "%lu,%3.3lu,%3.3lu" : "%lu%3.3lu%3.3lu",
280 (lnat)((x)/(ullong)1000000),
281 (lnat)((x)/(ullong)1000%(ullong)1000),
282 (lnat)((x)%(ullong)1000));
284 sprintf(s, (with_commas) ? "%lu,%3.3lu,%3.3lu,%3.3lu" : "%lu%3.3lu%3.3lu%3.3lu",
285 (lnat)((x)/(ullong)1000000000),
286 (lnat)((x)/(ullong)1000000%(ullong)1000),
287 (lnat)((x)/(ullong)1000%(ullong)1000),
288 (lnat)((x)%(ullong)1000));
293 // Can be used as a breakpoint to set on every heap check failure.
296 heapCheckFail( void )
302 * It seems that pthreads and signals interact oddly in OpenBSD & FreeBSD
303 * pthreads (and possibly others). When linking with -lpthreads, we
304 * have to use pthread_kill to send blockable signals. So use that
305 * when we have a threaded rts. So System.Posix.Signals will call
306 * genericRaise(), rather than raise(3).
308 int genericRaise(int sig) {
309 #if defined(THREADED_RTS) && (defined(openbsd_HOST_OS) || defined(freebsd_HOST_OS))
310 return pthread_kill(pthread_self(), sig);