CACAO
os.cpp
Go to the documentation of this file.
1 /* src/vm/os.cpp - system (OS) functions
2 
3  Copyright (C) 2007, 2008
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2008 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 
24 */
25 
26 
27 #include "config.h"
28 
29 #if defined(__DARWIN__)
30 # include <mach/mach.h>
31 # include <mach/mach_host.h>
32 # include <mach/host_info.h>
33 #endif
34 
35 /* this should work on BSD */
36 /* #include <sys/sysctl.h> */
37 
38 #include "mm/memory.hpp"
39 #include "toolbox/logging.hpp"
40 #include "vm/os.hpp"
41 #include "vm/vm.hpp"
42 
43 
44 /**
45  * Prints an error message and aborts the VM.
46  *
47  * @param text Error message to print.
48  */
49 void os::abort(const char* text, ...)
50 {
51  va_list ap;
52 
53  // Print the log message.
54  log_start();
55 
56  va_start(ap, text);
57  log_vprint(text, ap);
58  va_end(ap);
59 
60  log_finish();
61 
62  // Print a backtrace.
64 
65  // Now abort the VM.
66  os::abort();
67 }
68 
69 /**
70  * Prints a should not reach message and aborts the VM.
71  *
72  * @param text Error message to print.
73  */
74 void os::shouldnotreach(const char* text, ...)
75 {
76  va_list ap;
77 
78  // Print the log message.
79  log_start();
80 
81  log_print("should not reach: ");
82  va_start(ap, text);
83  log_vprint(text, ap);
84  va_end(ap);
85 
86  log_finish();
87 
88  // Print a backtrace.
90 
91  // Now abort the VM.
92  os::abort();
93 }
94 
95 /**
96  * Prints an unimplemented message and aborts the VM.
97  *
98  * @param text Error message to print.
99  */
100 void os::unimplemented(const char* text, ...)
101 {
102  va_list ap;
103 
104  // Print the log message.
105  log_start();
106 
107  log_print("not implemented yet: ");
108  va_start(ap, text);
109  log_vprint(text, ap);
110  va_end(ap);
111 
112  log_finish();
113 
114  // Print a backtrace.
116 
117  // Now abort the VM.
118  os::abort();
119 }
120 
121 /**
122  * Common code for both os::abort_errnum and os::abort_errno.
123  */
124 static void abort_verrnum(int errnum, const char* text, va_list ap)
125 {
126  // Print the log message.
127  log_start();
128 
129  log_vprint(text, ap);
130 
131  // Print the strerror-message of errnum.
132  log_print(": %s", os::strerror(errnum));
133 
134  log_finish();
135 
136  // Print a backtrace.
138 
139  // Now abort the VM.
140  os::abort();
141 }
142 
143 /**
144  * Prints an error message, appends ":" plus the strerror-message of
145  * errnum and aborts the VM.
146  *
147  * @param errnum Error number.
148  * @param text Error message to print.
149  */
150 void os::abort_errnum(int errnum, const char* text, ...)
151 {
152  va_list ap;
153 
154  va_start(ap, text);
155  abort_verrnum(errnum, text, ap);
156  va_end(ap);
157 }
158 
159 
160 /**
161  * Equal to abort_errnum, but uses errno to get the error number.
162  *
163  * @param text Error message to print.
164  */
165 void os::abort_errno(const char* text, ...)
166 {
167  va_list ap;
168 
169  va_start(ap, text);
170  abort_verrnum(errno, text, ap);
171  va_end(ap);
172 }
173 
174 
175 /**
176  * Return the current working directory.
177  *
178  * @return Pointer to a char array allocated by MNEW, or
179  * NULL if memory could not be allocated.
180  */
181 char* os::getcwd(void)
182 {
183  int32_t size = 1024;
184 
185  char* buf = MNEW(char, size);
186 
187  while (buf != NULL) {
188  if (getcwd(buf, size) != NULL)
189  return buf;
190 
191  MFREE(buf, char, size);
192 
193  /* too small buffer or a more serious problem */
194 
195  if (errno != ERANGE)
196  abort_errno("os::getcwd: getcwd failed");
197 
198  /* double the buffer size */
199 
200  size *= 2;
201 
202  buf = MNEW(char, size);
203  }
204 
205  return NULL;
206 }
207 
208 
209 /**
210  * Maps anonymous memory, even on systems not defining
211  * MAP_ANON(YMOUS).
212  *
213  * @param ...
214  */
215 void* os::mmap_anonymous(void *addr, size_t len, int prot, int flags)
216 {
217  void* p;
218 
219 #if defined(MAP_ANON) || defined(MAP_ANONYMOUS)
220  p = mmap(addr, len, prot,
221 # if defined(MAP_ANON)
222  MAP_ANON | flags,
223 # else
224  MAP_ANONYMOUS | flags,
225 # endif
226  -1, 0);
227 #else
228  int fd;
229 
230  fd = open("/dev/zero", O_RDONLY, 0);
231 
232  if (fd == -1)
233  os::abort_errno("os::mmap_anonymous: open failed");
234 
235  p = mmap(addr, len, prot, flags, fd, 0);
236 #endif
237 
238 #if defined(MAP_FAILED)
239  if (p == MAP_FAILED)
240 #else
241  if (p == (void *) -1)
242 #endif
243  os::abort_errno("os::mmap_anonymous: mmap failed");
244 
245  return p;
246 }
247 
248 
249 /**
250  * Print a C backtrace.
251  */
253 {
254 #define BACKTRACE_SIZE 100
255  void** array = new void*[SIZEOF_VOID_P * BACKTRACE_SIZE];
256 
257  // Get the backtrace.
258  int size = backtrace(array, BACKTRACE_SIZE);
259 
260  // Resolve the symbols.
261  char** strings = backtrace_symbols(array, size);
262 
263  log_println("Backtrace (%d stack frames):", size);
264 
265  for (int i = 0; i < size; i++)
266  log_println("%s", strings[i]);
267 
268  // We have to free the strings.
269  free(strings);
270 }
271 
272 
273 /**
274  * Returns the number of online processors in the system.
275  *
276  * @return Number of online processors.
277  */
279 {
280 #if defined(_SC_NPROC_ONLN)
281 
282  return (int) sysconf(_SC_NPROC_ONLN);
283 
284 #elif defined(_SC_NPROCESSORS_ONLN)
285 
286  return (int) sysconf(_SC_NPROCESSORS_ONLN);
287 
288 #elif defined(__DARWIN__)
289 
290  host_basic_info_data_t hinfo;
291  mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
292  kern_return_t rc;
293 
294  rc = host_info(mach_host_self(), HOST_BASIC_INFO,
295  (host_info_t) &hinfo, &hinfo_count);
296 
297  if (rc != KERN_SUCCESS) {
298  return -1;
299  }
300 
301  /* XXX michi: according to my infos this should be
302  hinfo.max_cpus, can someone please confirm or deny that? */
303  return (int) hinfo.avail_cpus;
304 
305 #elif defined(__FREEBSD__)
306 # error IMPLEMENT ME!
307 
308  /* this should work in BSD */
309  /*
310  int ncpu, mib[2], rc;
311  size_t len;
312 
313  mib[0] = CTL_HW;
314  mib[1] = HW_NCPU;
315  len = sizeof(ncpu);
316  rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
317 
318  return (int32_t) ncpu;
319  */
320 
321 #else
322 
323  return 1;
324 
325 #endif
326 }
327 
328 
329 // Legacy C interface.
330 
331 extern "C" {
332  void* os_mmap_anonymous(void *addr, size_t len, int prot, int flags) { return os::mmap_anonymous(addr, len, prot, flags); }
333 
334  int os_atoi(const char* nptr) { return os::atoi(nptr); }
335  int os_getpagesize(void) { return os::getpagesize(); }
336  void* os_memcpy(void* dest, const void* src, size_t n) { return os::memcpy(dest, src, n); }
337  void* os_memset(void* s, int c, size_t n) { return os::memset(s, c, n); }
338  char* os_strdup(const char* s) { return os::strdup(s); }
339  int os_strlen(const char* s) { return os::strlen(s); }
340 
341 }
342 
343 
344 /*
345  * These are local overrides for various environment variables in Emacs.
346  * Please do not remove this and leave it at the end of the file, where
347  * Emacs will automagically detect them.
348  * ---------------------------------------------------------------------
349  * Local variables:
350  * mode: c++
351  * indent-tabs-mode: t
352  * c-basic-offset: 4
353  * tab-width: 4
354  * End:
355  * vim:noexpandtab:sw=4:ts=4:
356  */
static void * memset(void *s, int c, size_t n)
Definition: os.hpp:501
static char * strerror(int errnum)
Definition: os.hpp:663
static int processors_online()
Returns the number of online processors in the system.
Definition: os.cpp:278
static int backtrace(void **array, int size)
Definition: os.hpp:232
static void abort_errno(const char *text,...)
Equal to abort_errnum, but uses errno to get the error number.
Definition: os.cpp:165
static void unimplemented()
Definition: os.hpp:695
static void print_backtrace()
Print a C backtrace.
Definition: os.cpp:252
void * os_mmap_anonymous(void *addr, size_t len, int prot, int flags)
Definition: os.cpp:332
void log_finish(void)
Definition: logging.cpp:117
void log_println(const char *text,...)
Definition: logging.cpp:193
static void free(void *ptr)
Definition: os.hpp:370
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
void * os_memcpy(void *dest, const void *src, size_t n)
Definition: os.cpp:336
static size_t strlen(const char *s)
Definition: os.hpp:672
static void abort_errnum(int errnum, const char *text,...)
Prints an error message, appends &quot;:&quot; plus the strerror-message of errnum and aborts the VM...
Definition: os.cpp:150
static int atoi(const char *nptr)
Definition: os.hpp:223
void log_print(const char *text,...)
Definition: logging.cpp:149
#define MFREE(ptr, type, num)
Definition: memory.hpp:97
static int getpagesize(void)
Definition: os.hpp:433
static char ** backtrace_symbols(void *const *array, int size)
Definition: os.hpp:242
void log_vprint(const char *text, va_list ap)
Definition: logging.cpp:135
int os_getpagesize(void)
Definition: os.cpp:335
void log_start(void)
Definition: logging.cpp:106
static char * getcwd(void)
Return the current working directory.
Definition: os.cpp:181
MIIterator i
static void * memcpy(void *dest, const void *src, size_t n)
Definition: os.hpp:492
static void abort()
Definition: os.hpp:196
char * os_strdup(const char *s)
Definition: os.cpp:338
#define MNEW(type, num)
Definition: memory.hpp:96
static void * mmap_anonymous(void *addr, size_t len, int prot, int flags)
Maps anonymous memory, even on systems not defining MAP_ANON(YMOUS).
Definition: os.cpp:215
void * os_memset(void *s, int c, size_t n)
Definition: os.cpp:337
static void shouldnotreach()
Definition: os.hpp:690
#define BACKTRACE_SIZE
int os_atoi(const char *nptr)
Definition: os.cpp:334
static void abort_verrnum(int errnum, const char *text, va_list ap)
Common code for both os::abort_errnum and os::abort_errno.
Definition: os.cpp:124
int os_strlen(const char *s)
Definition: os.cpp:339
static char * strdup(const char *s)
Definition: os.hpp:654