LCOV - code coverage report
Current view: top level - vm - os.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 82 12.2 %
Date: 2015-06-10 18:10:59 Functions: 2 17 11.8 %

          Line data    Source code
       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           0 : void os::abort(const char* text, ...)
      50             : {
      51             :         va_list ap;
      52             : 
      53             :         // Print the log message.
      54           0 :         log_start();
      55             : 
      56           0 :         va_start(ap, text);
      57           0 :         log_vprint(text, ap);
      58           0 :         va_end(ap);
      59             : 
      60           0 :         log_finish();
      61             : 
      62             :         // Print a backtrace.
      63           0 :         os::print_backtrace();
      64             : 
      65             :         // Now abort the VM.
      66           0 :         os::abort();
      67           0 : }
      68             : 
      69             : /**
      70             :  * Prints a should not reach message and aborts the VM.
      71             :  *
      72             :  * @param text Error message to print.
      73             :  */
      74           0 : void os::shouldnotreach(const char* text, ...)
      75             : {
      76             :         va_list ap;
      77             : 
      78             :         // Print the log message.
      79           0 :         log_start();
      80             : 
      81           0 :         log_print("should not reach: ");
      82           0 :         va_start(ap, text);
      83           0 :         log_vprint(text, ap);
      84           0 :         va_end(ap);
      85             : 
      86           0 :         log_finish();
      87             : 
      88             :         // Print a backtrace.
      89           0 :         os::print_backtrace();
      90             : 
      91             :         // Now abort the VM.
      92           0 :         os::abort();
      93           0 : }
      94             : 
      95             : /**
      96             :  * Prints an unimplemented message and aborts the VM.
      97             :  *
      98             :  * @param text Error message to print.
      99             :  */
     100           0 : void os::unimplemented(const char* text, ...)
     101             : {
     102             :         va_list ap;
     103             : 
     104             :         // Print the log message.
     105           0 :         log_start();
     106             : 
     107           0 :         log_print("not implemented yet: ");
     108           0 :         va_start(ap, text);
     109           0 :         log_vprint(text, ap);
     110           0 :         va_end(ap);
     111             : 
     112           0 :         log_finish();
     113             : 
     114             :         // Print a backtrace.
     115           0 :         os::print_backtrace();
     116             : 
     117             :         // Now abort the VM.
     118           0 :         os::abort();
     119           0 : }
     120             : 
     121             : /**
     122             :  * Common code for both os::abort_errnum and os::abort_errno.
     123             :  */
     124           0 : static void abort_verrnum(int errnum, const char* text, va_list ap)
     125             : {
     126             :         // Print the log message.
     127           0 :         log_start();
     128             : 
     129           0 :         log_vprint(text, ap);
     130             : 
     131             :         // Print the strerror-message of errnum.
     132           0 :         log_print(": %s", os::strerror(errnum));
     133             : 
     134           0 :         log_finish();
     135             : 
     136             :         // Print a backtrace.
     137           0 :         os::print_backtrace();
     138             : 
     139             :         // Now abort the VM.
     140           0 :         os::abort();
     141           0 : }
     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           0 : void os::abort_errnum(int errnum, const char* text, ...)
     151             : {
     152             :         va_list ap;
     153             : 
     154           0 :         va_start(ap, text);
     155           0 :         abort_verrnum(errnum, text, ap);
     156           0 :         va_end(ap);
     157           0 : }
     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           0 : void os::abort_errno(const char* text, ...)
     166             : {
     167             :         va_list ap;
     168             : 
     169           0 :         va_start(ap, text);
     170           0 :         abort_verrnum(errno, text, ap);
     171           0 :         va_end(ap);
     172           0 : }
     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         329 : char* os::getcwd(void)
     182             : {
     183         329 :         int32_t size = 1024;
     184             : 
     185         329 :         char* buf = MNEW(char, size);
     186             : 
     187         658 :         while (buf != NULL) {
     188         329 :                 if (getcwd(buf, size) != NULL)
     189         329 :                         return buf;
     190             : 
     191           0 :                 MFREE(buf, char, size);
     192             : 
     193             :                 /* too small buffer or a more serious problem */
     194             : 
     195           0 :                 if (errno != ERANGE)
     196           0 :                         abort_errno("os::getcwd: getcwd failed");
     197             : 
     198             :                 /* double the buffer size */
     199             : 
     200           0 :                 size *= 2;
     201             : 
     202           0 :                 buf = MNEW(char, size);
     203             :         }
     204             : 
     205           0 :         return NULL;
     206             : }
     207             : 
     208             : 
     209             : /**
     210             :  * Maps anonymous memory, even on systems not defining
     211             :  * MAP_ANON(YMOUS).
     212             :  *
     213             :  * @param ...
     214             :  */
     215         491 : 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         491 :                          -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         491 :         if (p == MAP_FAILED)
     240             : #else
     241             :         if (p == (void *) -1)
     242             : #endif
     243           0 :                 os::abort_errno("os::mmap_anonymous: mmap failed");
     244             : 
     245         491 :         return p;
     246             : }
     247             : 
     248             : 
     249             : /**
     250             :  * Print a C backtrace.
     251             :  */
     252           0 : void os::print_backtrace()
     253             : {
     254             : #define BACKTRACE_SIZE 100
     255           0 :         void** array = new void*[SIZEOF_VOID_P * BACKTRACE_SIZE];
     256             : 
     257             :         // Get the backtrace.
     258           0 :         int size = backtrace(array, BACKTRACE_SIZE);
     259             : 
     260             :         // Resolve the symbols.
     261           0 :         char** strings = backtrace_symbols(array, size);
     262             : 
     263           0 :         log_println("Backtrace (%d stack frames):", size);
     264             : 
     265           0 :         for (int i = 0; i < size; i++)
     266           0 :                 log_println("%s", strings[i]);
     267             : 
     268             :         // We have to free the strings.
     269           0 :         free(strings);
     270           0 : }
     271             : 
     272             : 
     273             : /**
     274             :  * Returns the number of online processors in the system.
     275             :  *
     276             :  * @return Number of online processors.
     277             :  */
     278           0 : int os::processors_online(void)
     279             : {
     280             : #if defined(_SC_NPROC_ONLN)
     281             : 
     282             :         return (int) sysconf(_SC_NPROC_ONLN);
     283             : 
     284             : #elif defined(_SC_NPROCESSORS_ONLN)
     285             : 
     286           0 :         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           0 :         void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags) { return os::mmap_anonymous(addr, len, prot, flags); }
     333             : 
     334           0 :         int    os_atoi(const char* nptr) { return os::atoi(nptr); }
     335           0 :         int    os_getpagesize(void) { return os::getpagesize(); }
     336           0 :         void*  os_memcpy(void* dest, const void* src, size_t n) { return os::memcpy(dest, src, n); }
     337           0 :         void*  os_memset(void* s, int c, size_t n) { return os::memset(s, c, n); }
     338           0 :         char*  os_strdup(const char* s) { return os::strdup(s); }
     339           0 :         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             :  */

Generated by: LCOV version 1.11