1/* 2 * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#include "darwin_shim.h" 24 25#include <mach/mach.h> 26#include <mach/mach_time.h> 27#include <sys/sysctl.h> 28#include <sys/time.h> 29#include <sys/errno.h> 30#include <unistd.h> 31#include <fnmatch.h> 32 33#include "lwp.h" /* In lieu of Solaris <sys/lwp.h> */ 34 35hrtime_t 36gethrtime(void) 37{ 38 uint64_t elapsed; 39 static uint64_t start; 40 static mach_timebase_info_data_t sTimebaseInfo = { 0, 0 }; 41 42 // If this is the first time we've run, get the timebase. 43 // We can use denom == 0 to indicate that sTimebaseInfo is 44 // uninitialised because it makes no sense to have a zero 45 // denominator in a fraction. 46 47 if ( sTimebaseInfo.denom == 0 ) { 48 (void) mach_timebase_info(&sTimebaseInfo); 49 start = mach_absolute_time(); 50 } 51 52 elapsed = mach_absolute_time() - start; 53 54 // Convert to nanoseconds. 55 // return (elapsed * (uint64_t)sTimebaseInfo.numer)/(uint64_t)sTimebaseInfo.denom; 56 57 // Provided the final result is representable in 64 bits the following maneuver will 58 // deliver that result without intermediate overflow. 59 if (sTimebaseInfo.denom == sTimebaseInfo.numer) 60 return elapsed; 61 else if (sTimebaseInfo.denom == 1) 62 return elapsed * (uint64_t)sTimebaseInfo.numer; 63 else { 64 // Decompose elapsed = eta32 * 2^32 + eps32: 65 uint64_t eta32 = elapsed >> 32; 66 uint64_t eps32 = elapsed & 0x00000000ffffffffLL; 67 68 uint32_t numer = sTimebaseInfo.numer, denom = sTimebaseInfo.denom; 69 70 // Form product of elapsed64 (decomposed) and numer: 71 uint64_t mu64 = numer * eta32; 72 uint64_t lambda64 = numer * eps32; 73 74 // Divide the constituents by denom: 75 uint64_t q32 = mu64/denom; 76 uint64_t r32 = mu64 - (q32 * denom); // mu64 % denom 77 78 return (q32 << 32) + ((r32 << 32) + lambda64)/denom; 79 } 80} 81 82projid_t getprojid(void) { return (projid_t) 0; } // Darwin has no notion of project. Always return 0. 83taskid_t gettaskid(void) { return (taskid_t) 0; } // Darwin has no notion of task. Always return 0. 84zoneid_t getzoneid(void) { return (zoneid_t) 0; } // Darwin has no notion of Solaris zones(5). Always return 0. 85 86int 87gmatch(const char *s, const char *p) 88{ 89 // OS X's fnmatch return value is inverted relative to Solaris's gmatch 90 return fnmatch( p, s, 0 ) == 0; 91} 92 93long 94sysinfo(int command, char *buf, long count) 95{ 96 switch (command) 97 { 98 int mib[2]; 99 size_t len; 100 101 case SI_RELEASE: 102 mib[0] = CTL_KERN; 103 mib[1] = KERN_OSRELEASE; 104 len = count; 105 return sysctl(mib, 2, (void *)buf, &len, NULL, 0); 106 107 case SI_SYSNAME: 108 mib[0] = CTL_KERN; 109 mib[1] = KERN_OSTYPE; 110 len = count; 111 return sysctl(mib, 2, (void *)buf, &len, NULL, 0); 112 113 case SI_ISALIST: 114#if defined(__i386__) 115 strlcpy( buf, "x86", count ); 116#elif defined(__x86_64__) 117 strlcpy( buf, "x86_64", count ); 118#elif defined(__arm64__) 119 strlcpy( buf, "arm64", count ); 120#elif defined(__arm__) 121 strlcpy( buf, "arm", count ); 122#else 123#error Unknown ISA 124#endif 125 return 1; 126 default: 127 return -1; 128 } 129 130 /* NOTREACHED */ 131 return 0; 132} 133 134// The following are used only for "assert()" 135int _rw_read_held(struct _rwlock *l){ return 1; } 136int _rw_write_held(struct _rwlock *l){ return 1; } 137int _mutex_held(struct _lwp_mutex *m){ return 1; } 138 139/* 140 * p_online() is only used to identify valid processorid's and only by testing the 141 * return value against -1. On Mac OS X processors are given consecutive id numbers 142 * in [0..hw.physicalcpu_max). 143 */ 144int 145p_online(processorid_t processorid, int flag) 146{ 147 static int ncpu = -1; 148 149 if (ncpu == -1) { 150 size_t len = sizeof(ncpu); 151 int mib[2] = { CTL_HW, HW_NCPU }; 152 153 (void)sysctl(mib, 2, (void *)&ncpu, &len, NULL, 0); 154 } 155 156 switch(flag) { 157 case P_STATUS: 158 if (processorid < ncpu) 159 return P_ONLINE; 160 /* FALLTHROUGH */ 161 default: 162 errno = EINVAL; 163 return -1; 164 } 165 /* NOTREACHED */ 166} 167 168#if defined(_elf_seterr) 169#undef _elf_seterr 170#endif 171void _elf_seterr(int lib_err, int sys_err); 172void _SHIM_elf_seterr(int x) { _elf_seterr( 0, x); } 173