Merged comment cleanup (forgot this before).
[cacao.git] / src / vm / os.cpp
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 /* NOTE: In this file we check for all system headers, because we wrap
30    all system calls into functions for better portability. */
31
32 #if defined(HAVE_ERRNO_H)
33 # include <errno.h>
34 #endif
35
36 #if defined(HAVE_STDINT_H)
37 # include <stdint.h>
38 #endif
39
40 #if defined(HAVE_STRING_H)
41 # include <string.h>
42 #endif
43
44 #if defined(HAVE_UNISTD_H)
45 # include <unistd.h>
46 #endif
47
48 #if defined(HAVE_SYS_MMAN_H)
49 # include <sys/mman.h>
50 #endif
51
52 #if defined(__DARWIN__)
53 # include <mach/mach.h>
54 # include <mach/mach_host.h>
55 # include <mach/host_info.h>
56 #endif
57
58 /* this should work on BSD */
59 /* #include <sys/sysctl.h> */
60
61 #include "vm/vm.hpp"
62
63
64 /**
65  * Maps anonymous memory, even on systems not defining
66  * MAP_ANON(YMOUS).
67  *
68  * @param ...
69  */
70 void* os::mmap_anonymous(void *addr, size_t len, int prot, int flags)
71 {
72         void* p;
73
74 #if defined(MAP_ANON) || defined(MAP_ANONYMOUS)
75         p = mmap(addr, len, prot,
76 # if defined(MAP_ANON)
77                          MAP_ANON | flags,
78 # else
79                          MAP_ANONYMOUS | flags,
80 # endif
81                          -1, 0);
82 #else
83         int fd;
84
85         fd = open("/dev/zero", O_RDONLY, 0);
86
87         if (fd == -1)
88                 VM::get_current()->abort_errno("os::mmap_anonymous: open failed");
89
90         p = mmap(addr, len, prot, flags, fd, 0);
91 #endif
92
93 #if defined(MAP_FAILED)
94         if (p == MAP_FAILED)
95 #else
96         if (p == (void *) -1)
97 #endif
98                 VM::get_current()->abort_errno("os::mmap_anonymous: mmap failed");
99
100         return p;
101 }
102
103
104 /**
105  * Print a C backtrace.
106  */
107 void os::print_backtrace()
108 {
109 #define BACKTRACE_SIZE 100
110         void** array = new void*[SIZEOF_VOID_P * BACKTRACE_SIZE];
111
112         // Get the backtrace.
113         int size = backtrace(array, BACKTRACE_SIZE);
114
115         // Resolve the symbols.
116         char** strings = backtrace_symbols(array, size);
117
118         log_println("Backtrace (%d stack frames):", size);
119
120         for (int i = 0; i < size; i++)
121                 log_println("%s", strings[i]);
122
123         // We have to free the strings.
124         free(strings);
125 }
126
127
128 /**
129  * Returns the number of online processors in the system.
130  *
131  * @return Number of online processors.
132  */
133 int os::processors_online(void)
134 {
135 #if defined(_SC_NPROC_ONLN)
136
137         return (int) sysconf(_SC_NPROC_ONLN);
138
139 #elif defined(_SC_NPROCESSORS_ONLN)
140
141         return (int) sysconf(_SC_NPROCESSORS_ONLN);
142
143 #elif defined(__DARWIN__)
144
145         host_basic_info_data_t hinfo;
146         mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
147         kern_return_t rc;
148
149         rc = host_info(mach_host_self(), HOST_BASIC_INFO,
150                                    (host_info_t) &hinfo, &hinfo_count);
151  
152         if (rc != KERN_SUCCESS) {
153                 return -1;
154         }
155
156         /* XXX michi: according to my infos this should be
157            hinfo.max_cpus, can someone please confirm or deny that? */
158         return (int) hinfo.avail_cpus;
159
160 #elif defined(__FREEBSD__)
161 # error IMPLEMENT ME!
162
163         /* this should work in BSD */
164         /*
165         int ncpu, mib[2], rc;
166         size_t len;
167
168         mib[0] = CTL_HW;
169         mib[1] = HW_NCPU;
170         len = sizeof(ncpu);
171         rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
172
173         return (int32_t) ncpu;
174         */
175
176 #else
177
178         return 1;
179
180 #endif
181 }
182
183
184 // Legacy C interface.
185
186 extern "C" {
187         void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags) { return os::mmap_anonymous(addr, len, prot, flags); }
188
189         void   os_abort(void) { os::abort(); }
190         int    os_access(const char* pathname, int mode) { return os::access(pathname, mode); }
191         int    os_atoi(const char* nptr) { return os::atoi(nptr); }
192         void*  os_calloc(size_t nmemb, size_t size) { return os::calloc(nmemb, size); }
193 #if defined(ENABLE_JRE_LAYOUT)
194         char*  os_dirname(char* path) { return os::dirname(path); }
195 #endif
196         int    os_dlclose(void* handle) { return os::dlclose(handle); }
197         char*  os_dlerror(void) { return os::dlerror(); }
198         void*  os_dlopen(const char* filename, int flag) { return os::dlopen(filename, flag); }
199         void*  os_dlsym(void* handle, const char* symbol) { return os::dlsym(handle, symbol); }
200         int    os_fclose(FILE* fp) { return os::fclose(fp); }
201         FILE*  os_fopen(const char* path, const char* mode) { return os::fopen(path, mode); }
202         size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { return os::fread(ptr, size, nmemb, stream); }
203         void   os_free(void* ptr) { os::free(ptr); }
204         int    os_getpagesize(void) { return os::getpagesize(); }
205         void*  os_memcpy(void* dest, const void* src, size_t n) { return os::memcpy(dest, src, n); }
206         void*  os_memset(void* s, int c, size_t n) { return os::memset(s, c, n); }
207         int    os_mprotect(void* addr, size_t len, int prot) { return os::mprotect(addr, len, prot); }
208         int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*)) { return os::scandir(dir, namelist, filter, compar); }
209         int    os_stat(const char* path, struct stat* buf) { return os::stat(path, buf); }
210         char*  os_strcat(char* dest, const char* src) { return os::strcat(dest, src); }
211         char*  os_strcpy(char* dest, const char* src) { return os::strcpy(dest, src); }
212         char*  os_strdup(const char* s) { return os::strdup(s); }
213         int    os_strlen(const char* s) { return os::strlen(s); }
214
215 }
216
217
218 /*
219  * These are local overrides for various environment variables in Emacs.
220  * Please do not remove this and leave it at the end of the file, where
221  * Emacs will automagically detect them.
222  * ---------------------------------------------------------------------
223  * Local variables:
224  * mode: c++
225  * indent-tabs-mode: t
226  * c-basic-offset: 4
227  * tab-width: 4
228  * End:
229  * vim:noexpandtab:sw=4:ts=4:
230  */