Skip to content

Commit a9b8b46

Browse files
committed
Initial version of native library for Mac OS X
1 parent 9a7fa58 commit a9b8b46

2 files changed

Lines changed: 165 additions & 0 deletions

File tree

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright 2011-2012 Peter Lawrey & Jerry Shea
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <jni.h>
18+
#include <mach/thread_policy.h>
19+
#include <pthread.h>
20+
#include "vanilla_java_affinity_impl_NativeAffinity.h"
21+
#include "vanilla_java_busywaiting_impl_JNIBusyWaiting.h"
22+
#include "vanilla_java_clock_impl_JNIClock.h"
23+
24+
/*
25+
* Class: vanilla_java_affinity_impl_NativeAffinity
26+
* Method: getAffinity0
27+
* Signature: ()J
28+
*/
29+
JNIEXPORT jlong JNICALL Java_vanilla_java_affinity_impl_NativeAffinity_getAffinity0
30+
(JNIEnv *env, jclass c) {
31+
32+
thread_port_t threadport = pthread_mach_thread_np(pthread_self());
33+
34+
struct thread_affinity_policy policy;
35+
policy.affinity_tag = 0;
36+
mach_msg_type_number_t count = THREAD_AFFINITY_POLICY_COUNT;
37+
boolean_t get_default = FALSE;
38+
39+
if ((thread_policy_get(threadport,
40+
THREAD_AFFINITY_POLICY, (thread_policy_t)&policy,
41+
&count, &get_default)) != KERN_SUCCESS) {
42+
return ~0LL;
43+
}
44+
45+
return (jlong) policy.affinity_tag;
46+
}
47+
48+
/*
49+
* Class: vanilla_java_affinity_NativeAffinity
50+
* Method: setAffinity0
51+
* Signature: (J)V
52+
*/
53+
JNIEXPORT void JNICALL Java_vanilla_java_affinity_impl_NativeAffinity_setAffinity0
54+
(JNIEnv *env, jclass c, jlong affinity) {
55+
56+
thread_port_t threadport = pthread_mach_thread_np(pthread_self());
57+
58+
struct thread_affinity_policy policy;
59+
policy.affinity_tag = affinity;
60+
61+
int rc = thread_policy_set(threadport,
62+
THREAD_AFFINITY_POLICY, (thread_policy_t)&policy,
63+
THREAD_AFFINITY_POLICY_COUNT);
64+
if (rc != KERN_SUCCESS) {
65+
jclass ex = (*env)->FindClass(env, "java/lang/RuntimeException");
66+
char msg[100];
67+
sprintf(msg, "Bad return value from thread_policy_set: %d", rc);
68+
(*env)->ThrowNew(env, ex, msg);
69+
}
70+
}
71+
72+
// below code copied directly from vanilla_java_affinity_impl_NativeAffinity.c
73+
74+
#if defined(__i386__)
75+
static __inline__ unsigned long long rdtsc(void) {
76+
unsigned long long int x;
77+
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
78+
return x;
79+
80+
}
81+
82+
#elif defined(__x86_64__)
83+
static __inline__ unsigned long long rdtsc(void) {
84+
unsigned hi, lo;
85+
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
86+
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
87+
}
88+
89+
#elif defined(__MIPS_32__)
90+
#define rdtsc(dest) \
91+
_ _asm_ _ _ _volatile_ _("mfc0 %0,$9; nop" : "=r" (dest))
92+
93+
#elif defined(__MIPS_SGI__)
94+
#include <time.h>
95+
96+
static __inline__ unsigned long long rdtsc (void) {
97+
struct timespec tp;
98+
clock_gettime (CLOCK_SGI_CYCLE, &tp);
99+
return (unsigned long long)(tp.tv_sec * (unsigned long long)1000000000) + (unsigned long long)tp.tv_nsec;
100+
}
101+
#endif
102+
103+
/*
104+
* Class: vanilla_java_affinity_NativeAffinity
105+
* Method: rdtsc0
106+
* Signature: ()J
107+
*/
108+
JNIEXPORT jlong JNICALL Java_vanilla_java_clock_impl_JNIClock_rdtsc0
109+
(JNIEnv *env, jclass c) {
110+
return (jlong) rdtsc();
111+
}
112+
113+
// From http://locklessinc.com/articles/locks/
114+
/* Compile read-write barrier */
115+
#define barrier() asm volatile("": : :"memory")
116+
117+
/* Pause instruction to prevent excess processor bus usage */
118+
#define cpu_relax() asm volatile("pause\n": : :"memory")
119+
120+
/*
121+
* Class: vanilla_java_busywaiting_impl_JNIBusyWaiting
122+
* Method: pause0
123+
* Signature: ()V
124+
*/
125+
JNIEXPORT void JNICALL Java_vanilla_java_busywaiting_impl_JNIBusyWaiting_pause0
126+
(JNIEnv *env, jclass c) {
127+
cpu_relax();
128+
}
129+
130+
/*
131+
* Class: vanilla_java_busywaiting_impl_JNIBusyWaiting
132+
* Method: whileEqual0
133+
* Signature: (JIJ)J
134+
*/
135+
JNIEXPORT jlong JNICALL Java_vanilla_java_busywaiting_impl_JNIBusyWaiting_whileEqual0
136+
(JNIEnv *env, jclass c, jlong address0, jint iterations, jlong value) {
137+
volatile jlong * address = (volatile jlong *) address0;
138+
barrier();
139+
jlong value2 = *address;
140+
while(value2 == value && iterations-- > 0) {
141+
cpu_relax();
142+
barrier();
143+
value2 = *address;
144+
}
145+
return value2;
146+
}
147+
148+
/*
149+
* Class: vanilla_java_busywaiting_impl_JNIBusyWaiting
150+
* Method: whileLessThan0
151+
* Signature: (JIJ)J
152+
*/
153+
JNIEXPORT jlong JNICALL Java_vanilla_java_busywaiting_impl_JNIBusyWaiting_whileLessThan0
154+
(JNIEnv *env, jclass c, jlong address0, jint iterations, jlong value) {
155+
volatile jlong * address = (volatile jlong *) address0;
156+
barrier();
157+
jlong value2 = *address;
158+
while(value2 < value && iterations-- > 0) {
159+
cpu_relax();
160+
barrier();
161+
value2 = *address;
162+
}
163+
return value2;
164+
}
165+
Binary file not shown.

0 commit comments

Comments
 (0)