* src/native/vm/sun_misc_Unsafe.cpp (Java_sun_misc_Unsafe_getLoadAverage): Added.
[cacao.git] / src / vm / os.hpp
1 /* src/vm/os.hpp - system (OS) functions
2
3    Copyright (C) 2007, 2008, 2009
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 #ifndef _OS_HPP
28 #define _OS_HPP
29
30 #include "config.h"
31
32 // NOTE: In this file we check for all system headers, because we wrap
33 // all system calls into inline functions for better portability.
34
35 // Please don't include CACAO headers here as this header should be a
36 // very low-level one.
37
38 #if defined(HAVE_DIRENT_H)
39 # include <dirent.h>
40 #endif
41
42 #if defined(HAVE_DLFCN_H)
43 # include <dlfcn.h>
44 #endif
45
46 #if defined(HAVE_ERRNO_H)
47 # include <errno.h>
48 #endif
49
50 #if defined(HAVE_EXECINFO_H)
51 # include <execinfo.h>
52 #endif
53
54 #if defined(HAVE_FCNTL_H)
55 # include <fcntl.h>
56 #endif
57
58 #if defined(ENABLE_JRE_LAYOUT)
59 # if defined(HAVE_LIBGEN_H)
60 #  include <libgen.h>
61 # endif
62 #endif
63
64 #if defined(HAVE_SIGNAL_H)
65 # include <signal.h>
66 #endif
67
68 #if defined(HAVE_STDARG_H)
69 # include <stdarg.h>
70 #endif
71
72 #if defined(HAVE_STDINT_H)
73 # include <stdint.h>
74 #endif
75
76 #if defined(HAVE_STDIO_H)
77 # include <stdio.h>
78 #endif
79
80 #if defined(HAVE_STDLIB_H)
81 # include <stdlib.h>
82 #endif
83
84 #if defined(HAVE_STRING_H)
85 # include <string.h>
86 #endif
87
88 #if defined(HAVE_UNISTD_H)
89 # include <unistd.h>
90 #endif
91
92 #if defined(HAVE_SYS_MMAN_H)
93 # include <sys/mman.h>
94 #endif
95
96 #if defined(HAVE_SYS_SOCKET_H)
97 # include <sys/socket.h>
98 #endif
99
100 #if defined(HAVE_SYS_STAT_H)
101 # include <sys/stat.h>
102 #endif
103
104 #if defined(HAVE_SYS_TYPES_H)
105 # include <sys/types.h>
106 #endif
107
108
109 #ifdef __cplusplus
110
111 // Class wrapping system (OS) functions.
112 class os {
113 public:
114         // Inline functions.
115         static inline void    abort();
116         static inline int     accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
117         static inline int     access(const char *pathname, int mode);
118         static inline int     atoi(const char* nptr);
119         static inline int     backtrace(void** array, int size);
120         static inline char**  backtrace_symbols(void* const* array, int size) throw ();
121         static inline void*   calloc(size_t nmemb, size_t size);
122         static inline int     close(int fd);
123         static inline int     connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
124 #if defined(ENABLE_JRE_LAYOUT)
125         static inline char*   dirname(char* path);
126 #endif
127         static inline int     dlclose(void* handle);
128         static inline char*   dlerror(void);
129         static inline void*   dlopen(const char* filename, int flag);
130         static inline void*   dlsym(void* handle, const char* symbol);
131         static inline int     fclose(FILE* fp);
132         static inline FILE*   fopen(const char* path, const char* mode);
133         static inline int     fprintf(FILE* stream, const char* format, ...);
134         static inline size_t  fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
135         static inline void    free(void* ptr);
136         static inline char*   getenv(const char* name);
137         static inline int     gethostname(char* name, size_t len);
138         static inline int     getloadavg(double loadavg[], int nelem);
139         static inline int     getpagesize(void);
140         static inline int     getsockname(int s, struct sockaddr* name, socklen_t* namelen);
141         static inline int     getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
142         static inline int     listen(int sockfd, int backlog);
143         static inline void*   malloc(size_t size);
144         static inline void*   memcpy(void* dest, const void* src, size_t n);
145         static inline void*   memset(void* s, int c, size_t n);
146         static inline int     mprotect(void* addr, size_t len, int prot);
147         static inline ssize_t readlink(const char* path, char* buf, size_t bufsiz);
148         static inline int     scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
149         static inline ssize_t send(int s, const void* buf, size_t len, int flags);
150         static inline int     setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen);
151         static inline int     shutdown(int s, int how);
152         static inline int     socket(int domain, int type, int protocol);
153         static inline int     stat(const char* path, struct stat* buf);
154 #if defined(__SOLARIS__)
155         static inline int     str2sig(const char* str, int* signum);
156 #endif
157         static inline char*   strcat(char* dest, const char* src);
158         static inline int     strcmp(const char* s1, const char* s2);
159         static inline char*   strcpy(char* dest, const char* src);
160         static inline char*   strdup(const char* s);
161         static inline size_t  strlen(const char* s);
162         static inline char*   strerror(int errnum);
163
164         // Convenience functions.
165         static void  abort(const char* text, ...);
166         static void  abort_errnum(int errnum, const char* text, ...);
167         static void  abort_errno(const char* text, ...);
168         static void* mmap_anonymous(void *addr, size_t len, int prot, int flags);
169         static void  print_backtrace();
170         static int   processors_online();
171
172         // Template helper
173         template<class F1, class F2>
174         static int call_scandir(int (*scandir)(const char *, struct dirent ***, F1, F2), const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *));
175 };
176
177
178 inline void os::abort(void)
179 {
180 #if defined(HAVE_ABORT)
181         ::abort();
182 #else
183 # error abort not available
184 #endif
185 }
186
187 inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
188 {
189 #if defined(HAVE_ACCEPT)
190         return ::accept(sockfd, addr, addrlen);
191 #else
192 # error accept not available
193 #endif
194 }
195
196 inline int os::access(const char* pathname, int mode)
197 {
198 #if defined(HAVE_ACCESS)
199         return ::access(pathname, mode);
200 #else
201 # error access not available
202 #endif
203 }
204
205 inline int os::atoi(const char* nptr)
206 {
207 #if defined(HAVE_ATOI)
208         return ::atoi(nptr);
209 #else
210 # error atoi not available
211 #endif
212 }
213
214 inline int os::backtrace(void** array, int size)
215 {
216 #if defined(HAVE_BACKTRACE)
217         return ::backtrace(array, size);
218 #else
219         fprintf(stderr, "os::backtrace: Not available.");
220         return 0;
221 #endif
222 }
223
224 inline char** os::backtrace_symbols(void* const* array, int size) throw ()
225 {
226 #if defined(HAVE_BACKTRACE_SYMBOLS)
227         return ::backtrace_symbols(array, size);
228 #else
229         fprintf(stderr, "os::backtrace_symbols: Not available.");
230         return NULL;
231 #endif
232 }
233
234 inline void* os::calloc(size_t nmemb, size_t size)
235 {
236 #if defined(HAVE_CALLOC)
237         return ::calloc(nmemb, size);
238 #else
239 # error calloc not available
240 #endif
241 }
242
243 inline int os::close(int fd)
244 {
245 #if defined(HAVE_CLOSE)
246         return ::close(fd);
247 #else
248 # error close not available
249 #endif
250 }
251
252 inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
253 {
254 #if defined(HAVE_CONNECT)
255         return ::connect(sockfd, serv_addr, addrlen);
256 #else
257 # error connect not available
258 #endif
259 }
260
261 #if defined(ENABLE_JRE_LAYOUT)
262 inline char* os::dirname(char* path)
263 {
264 #if defined(HAVE_DIRNAME)
265         return ::dirname(path);
266 #else
267 # error dirname not available
268 #endif
269 }
270 #endif
271
272 inline int os::dlclose(void* handle)
273 {
274 #if defined(HAVE_DLCLOSE)
275         return ::dlclose(handle);
276 #else
277 # error dlclose not available
278 #endif
279 }
280
281 inline char* os::dlerror(void)
282 {
283 #if defined(HAVE_DLERROR)
284         // At least FreeBSD defines dlerror() to return a const char*, so
285         // we simply cast it.
286         return (char*) ::dlerror();
287 #else
288 # error dlerror not available
289 #endif
290 }
291
292 inline void* os::dlopen(const char* filename, int flag)
293 {
294 #if defined(HAVE_DLOPEN)
295         return ::dlopen(filename, flag);
296 #else
297 # error dlopen not available
298 #endif
299 }
300
301 inline void* os::dlsym(void* handle, const char* symbol)
302 {
303 #if defined(HAVE_DLSYM)
304         return ::dlsym(handle, symbol);
305 #else
306 # error dlsym not available
307 #endif
308 }
309
310 inline int os::fclose(FILE* fp)
311 {
312 #if defined(HAVE_FCLOSE)
313         return ::fclose(fp);
314 #else
315 # error fclose not available
316 #endif
317 }
318
319 inline FILE* os::fopen(const char* path, const char* mode)
320 {
321 #if defined(HAVE_FOPEN)
322         return ::fopen(path, mode);
323 #else
324 # error fopen not available
325 #endif
326 }
327
328 inline int os::fprintf(FILE* stream, const char* format, ...)
329 {
330 #if defined(HAVE_FPRINTF)
331         va_list ap;
332         va_start(ap, format);
333         int result = ::vfprintf(stream, format, ap);
334         va_end(ap);
335         return result;
336 #else
337 # error fprintf not available
338 #endif
339 }
340
341 inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
342 {
343 #if defined(HAVE_FREAD)
344         return ::fread(ptr, size, nmemb, stream);
345 #else
346 # error fread not available
347 #endif
348 }
349
350 inline void os::free(void* ptr)
351 {
352 #if defined(HAVE_FREE)
353         ::free(ptr);
354 #else
355 # error free not available
356 #endif
357 }
358
359 inline static int system_fsync(int fd)
360 {
361 #if defined(HAVE_FSYNC)
362         return fsync(fd);
363 #else
364 # error fsync not available
365 #endif
366 }
367
368 inline static int system_ftruncate(int fd, off_t length)
369 {
370 #if defined(HAVE_FTRUNCATE)
371         return ftruncate(fd, length);
372 #else
373 # error ftruncate not available
374 #endif
375 }
376
377 inline char* os::getenv(const char* name)
378 {
379 #if defined(HAVE_GETENV)
380         return ::getenv(name);
381 #else
382 # error getenv not available
383 #endif
384 }
385
386 inline int os::gethostname(char* name, size_t len)
387 {
388 #if defined(HAVE_GETHOSTNAME)
389         return ::gethostname(name, len);
390 #else
391 # error gethostname not available
392 #endif
393 }
394
395 inline int os::getloadavg(double loadavg[], int nelem)
396 {
397 #if defined(HAVE_GETLOADAVG)
398         return ::getloadavg(loadavg, nelem);
399 #else
400 # error getloadavg not available
401 #endif
402 }
403
404 inline int os::getpagesize(void)
405 {
406 #if defined(HAVE_GETPAGESIZE)
407         return ::getpagesize();
408 #else
409 # error getpagesize not available
410 #endif
411 }
412
413 inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
414 {
415 #if defined(HAVE_GETSOCKNAME)
416         return ::getsockname(s, name, namelen);
417 #else
418 # error getsockname not available
419 #endif
420 }
421
422 inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
423 {
424 #if defined(HAVE_GETSOCKOPT)
425         return ::getsockopt(s, level, optname, optval, optlen);
426 #else
427 # error getsockopt not available
428 #endif
429 }
430
431 inline int os::listen(int sockfd, int backlog)
432 {
433 #if defined(HAVE_LISTEN)
434         return ::listen(sockfd, backlog);
435 #else
436 # error listen not available
437 #endif
438 }
439
440 inline static off_t system_lseek(int fildes, off_t offset, int whence)
441 {
442 #if defined(HAVE_LSEEK)
443         return lseek(fildes, offset, whence);
444 #else
445 # error lseek not available
446 #endif
447 }
448
449 inline void* os::malloc(size_t size)
450 {
451 #if defined(HAVE_MALLOC)
452         return ::malloc(size);
453 #else
454 # error malloc not available
455 #endif
456 }
457
458 inline void* os::memcpy(void* dest, const void* src, size_t n)
459 {
460 #if defined(HAVE_MEMCPY)
461         return ::memcpy(dest, src, n);
462 #else
463 # error memcpy not available
464 #endif
465 }
466
467 inline void* os::memset(void* s, int c, size_t n)
468 {
469 #if defined(HAVE_MEMSET)
470         return ::memset(s, c, n);
471 #else
472 # error memset not available
473 #endif
474 }
475
476 inline int os::mprotect(void* addr, size_t len, int prot)
477 {
478 #if defined(HAVE_MPROTECT)
479         return ::mprotect(addr, len, prot);
480 #else
481 # error mprotect not available
482 #endif
483 }
484
485 inline static int system_open(const char *pathname, int flags, mode_t mode)
486 {
487 #if defined(HAVE_OPEN)
488         return open(pathname, flags, mode);
489 #else
490 # error open not available
491 #endif
492 }
493
494 inline static ssize_t system_read(int fd, void *buf, size_t count)
495 {
496 #if defined(HAVE_READ)
497         return read(fd, buf, count);
498 #else
499 # error read not available
500 #endif
501 }
502
503 inline ssize_t os::readlink(const char* path, char* buf, size_t bufsiz)
504 {
505 #if defined(HAVE_READLINK)
506         return ::readlink(path, buf, bufsiz);
507 #else
508 # error readlink not available
509 #endif
510 }
511
512 inline static void *system_realloc(void *ptr, size_t size)
513 {
514 #if defined(HAVE_REALLOC)
515         return realloc(ptr, size);
516 #else
517 # error realloc not available
518 #endif
519 }
520
521 template<class F1, class F2>
522 inline int os::call_scandir(int (*scandir)(const char *, struct dirent ***, F1, F2), const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
523 {
524         return scandir(dir, namelist, (F1) filter, (F2) compar);
525 }
526
527 inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
528 {
529 #if defined(HAVE_SCANDIR)
530         return call_scandir(::scandir, dir, namelist, filter, compar);
531 #else
532 # error scandir not available
533 #endif
534 }
535
536 inline ssize_t os::send(int s, const void* buf, size_t len, int flags)
537 {
538         // TODO Should be restartable on Linux and interruptible on Solaris.
539 #if defined(HAVE_SEND)
540         return ::send(s, buf, len, flags);
541 #else
542 # error send not available
543 #endif
544 }
545
546 inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
547 {
548 #if defined(HAVE_SETSOCKOPT)
549         return ::setsockopt(s, level, optname, optval, optlen);
550 #else
551 # error setsockopt not available
552 #endif
553 }
554
555 inline int os::shutdown(int s, int how)
556 {
557 #if defined(HAVE_SHUTDOWN)
558         return ::shutdown(s, how);
559 #else
560 # error shutdown not available
561 #endif
562 }
563
564 inline int os::socket(int domain, int type, int protocol)
565 {
566 #if defined(HAVE_SOCKET)
567         return ::socket(domain, type, protocol);
568 #else
569 # error socket not available
570 #endif
571 }
572
573 inline int os::stat(const char* path, struct stat* buf)
574 {
575 #if defined(HAVE_STAT)
576         return ::stat(path, buf);
577 #else
578 # error stat not available
579 #endif
580 }
581
582 #if defined(__SOLARIS__)
583 inline int os::str2sig(const char* str, int* signum)
584 {
585 #if defined(HAVE_STR2SIG)
586         return ::str2sig(str, signum);
587 #else
588 # error str2sig not available
589 #endif
590 }
591 #endif
592
593 inline char* os::strcat(char* dest, const char* src)
594 {
595 #if defined(HAVE_STRCAT)
596         return ::strcat(dest, src);
597 #else
598 # error strcat not available
599 #endif
600 }
601
602 inline int os::strcmp(const char* s1, const char* s2)
603 {
604 #if defined(HAVE_STRCMP)
605         return ::strcmp(s1, s2);
606 #else
607 # error strcmp not available
608 #endif
609 }
610
611 inline char* os::strcpy(char* dest, const char* src)
612 {
613 #if defined(HAVE_STRCPY)
614         return ::strcpy(dest, src);
615 #else
616 # error strcpy not available
617 #endif
618 }
619
620 inline char* os::strdup(const char* s)
621 {
622 #if defined(HAVE_STRDUP)
623         return ::strdup(s);
624 #else
625 # error strdup not available
626 #endif
627 }
628
629 inline char* os::strerror(int errnum)
630 {
631 #if defined(HAVE_STRERROR)
632         return ::strerror(errnum);
633 #else
634 # error strerror not available
635 #endif
636 }
637
638 inline size_t os::strlen(const char* s)
639 {
640 #if defined(HAVE_STRLEN)
641         return ::strlen(s);
642 #else
643 # error strlen not available
644 #endif
645 }
646
647 inline static ssize_t system_write(int fd, const void *buf, size_t count)
648 {
649 #if defined(HAVE_WRITE)
650         return write(fd, buf, count);
651 #else
652 # error write not available
653 #endif
654 }
655
656 #else
657
658 void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
659
660 void   os_abort(void);
661 int    os_access(const char* pathname, int mode);
662 int    os_atoi(const char* nptr);
663 void*  os_calloc(size_t nmemb, size_t size);
664 char*  os_dirname(char* path);
665 char*  os_dlerror(void);
666 void*  os_dlsym(void* handle, const char* symbol);
667 int    os_fclose(FILE* fp);
668 FILE*  os_fopen(const char* path, const char* mode);
669 size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
670 void   os_free(void* ptr);
671 int    os_getpagesize(void);
672 void*  os_memcpy(void* dest, const void* src, size_t n);
673 void*  os_memset(void* s, int c, size_t n);
674 int    os_mprotect(void* addr, size_t len, int prot);
675 int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
676 int    os_stat(const char* path, struct stat* buf);
677 char*  os_strcat(char* dest, const char* src);
678 char*  os_strcpy(char* dest, const char* src);
679 char*  os_strdup(const char* s);
680 int    os_strlen(const char* s);
681
682 #endif
683
684 #endif // _OS_HPP
685
686
687 /*
688  * These are local overrides for various environment variables in Emacs.
689  * Please do not remove this and leave it at the end of the file, where
690  * Emacs will automagically detect them.
691  * ---------------------------------------------------------------------
692  * Local variables:
693  * mode: c++
694  * indent-tabs-mode: t
695  * c-basic-offset: 4
696  * tab-width: 4
697  * End:
698  * vim:noexpandtab:sw=4:ts=4:
699  */