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