149 // |
149 // |
150 // This interface should be declared in os_linux_i486.hpp, but |
150 // This interface should be declared in os_linux_i486.hpp, but |
151 // that file provides extensions to the os class and not the |
151 // that file provides extensions to the os class and not the |
152 // Linux class. |
152 // Linux class. |
153 static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc, |
153 static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc, |
154 intptr_t** ret_sp, intptr_t** ret_fp); |
154 intptr_t** ret_sp, intptr_t** ret_fp); |
155 |
155 |
156 // This boolean allows users to forward their own non-matching signals |
156 // This boolean allows users to forward their own non-matching signals |
157 // to JVM_handle_linux_signal, harmlessly. |
157 // to JVM_handle_linux_signal, harmlessly. |
158 static bool signal_handlers_are_installed; |
158 static bool signal_handlers_are_installed; |
159 |
159 |
220 } |
220 } |
221 |
221 |
222 static jlong fast_thread_cpu_time(clockid_t clockid); |
222 static jlong fast_thread_cpu_time(clockid_t clockid); |
223 |
223 |
224 // pthread_cond clock suppport |
224 // pthread_cond clock suppport |
225 private: |
225 private: |
226 static pthread_condattr_t _condattr[1]; |
226 static pthread_condattr_t _condattr[1]; |
227 |
227 |
228 public: |
228 public: |
229 static pthread_condattr_t* condAttr() { return _condattr; } |
229 static pthread_condattr_t* condAttr() { return _condattr; } |
230 |
230 |
231 // Stack repair handling |
231 // Stack repair handling |
232 |
232 |
233 // none present |
233 // none present |
234 |
234 |
235 // LinuxThreads work-around for 6292965 |
235 // LinuxThreads work-around for 6292965 |
236 static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); |
236 static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); |
237 |
237 |
238 private: |
238 private: |
239 typedef int (*sched_getcpu_func_t)(void); |
239 typedef int (*sched_getcpu_func_t)(void); |
240 typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); |
240 typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); |
241 typedef int (*numa_max_node_func_t)(void); |
241 typedef int (*numa_max_node_func_t)(void); |
242 typedef int (*numa_available_func_t)(void); |
242 typedef int (*numa_available_func_t)(void); |
243 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); |
243 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); |
260 static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } |
260 static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } |
261 static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } |
261 static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } |
262 static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } |
262 static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } |
263 static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } |
263 static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } |
264 static int sched_getcpu_syscall(void); |
264 static int sched_getcpu_syscall(void); |
265 public: |
265 public: |
266 static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } |
266 static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } |
267 static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { |
267 static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { |
268 return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1; |
268 return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1; |
269 } |
269 } |
270 static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; } |
270 static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; } |
285 static int get_node_by_cpu(int cpu_id); |
285 static int get_node_by_cpu(int cpu_id); |
286 }; |
286 }; |
287 |
287 |
288 |
288 |
289 class PlatformEvent : public CHeapObj<mtInternal> { |
289 class PlatformEvent : public CHeapObj<mtInternal> { |
290 private: |
290 private: |
291 double CachePad[4]; // increase odds that _mutex is sole occupant of cache line |
291 double CachePad[4]; // increase odds that _mutex is sole occupant of cache line |
292 volatile int _Event; |
292 volatile int _Event; |
293 volatile int _nParked; |
293 volatile int _nParked; |
294 pthread_mutex_t _mutex[1]; |
294 pthread_mutex_t _mutex[1]; |
295 pthread_cond_t _cond[1]; |
295 pthread_cond_t _cond[1]; |
296 double PostPad[2]; |
296 double PostPad[2]; |
297 Thread * _Assoc; |
297 Thread * _Assoc; |
298 |
298 |
299 public: // TODO-FIXME: make dtor private |
299 public: // TODO-FIXME: make dtor private |
300 ~PlatformEvent() { guarantee(0, "invariant"); } |
300 ~PlatformEvent() { guarantee(0, "invariant"); } |
301 |
301 |
302 public: |
302 public: |
303 PlatformEvent() { |
303 PlatformEvent() { |
304 int status; |
304 int status; |
305 status = pthread_cond_init (_cond, os::Linux::condAttr()); |
305 status = pthread_cond_init (_cond, os::Linux::condAttr()); |
306 assert_status(status == 0, status, "cond_init"); |
306 assert_status(status == 0, status, "cond_init"); |
307 status = pthread_mutex_init (_mutex, NULL); |
307 status = pthread_mutex_init (_mutex, NULL); |
308 assert_status(status == 0, status, "mutex_init"); |
308 assert_status(status == 0, status, "mutex_init"); |
309 _Event = 0; |
309 _Event = 0; |
310 _nParked = 0; |
310 _nParked = 0; |
311 _Assoc = NULL; |
311 _Assoc = NULL; |
312 } |
312 } |
313 |
313 |
314 // Use caution with reset() and fired() -- they may require MEMBARs |
314 // Use caution with reset() and fired() -- they may require MEMBARs |
315 void reset() { _Event = 0; } |
315 void reset() { _Event = 0; } |
316 int fired() { return _Event; } |
316 int fired() { return _Event; } |
317 void park(); |
317 void park(); |
318 void unpark(); |
318 void unpark(); |
319 int park(jlong millis); // relative timed-wait only |
319 int park(jlong millis); // relative timed-wait only |
320 void SetAssociation(Thread * a) { _Assoc = a; } |
320 void SetAssociation(Thread * a) { _Assoc = a; } |
321 }; |
321 }; |
322 |
322 |
323 class PlatformParker : public CHeapObj<mtInternal> { |
323 class PlatformParker : public CHeapObj<mtInternal> { |
324 protected: |
324 protected: |
325 enum { |
325 enum { |
326 REL_INDEX = 0, |
326 REL_INDEX = 0, |
327 ABS_INDEX = 1 |
327 ABS_INDEX = 1 |
328 }; |
328 }; |
329 int _cur_index; // which cond is in use: -1, 0, 1 |
329 int _cur_index; // which cond is in use: -1, 0, 1 |
330 pthread_mutex_t _mutex[1]; |
330 pthread_mutex_t _mutex[1]; |
331 pthread_cond_t _cond[2]; // one for relative times and one for abs. |
331 pthread_cond_t _cond[2]; // one for relative times and one for abs. |
332 |
332 |
333 public: // TODO-FIXME: make dtor private |
333 public: // TODO-FIXME: make dtor private |
334 ~PlatformParker() { guarantee(0, "invariant"); } |
334 ~PlatformParker() { guarantee(0, "invariant"); } |
335 |
335 |
336 public: |
336 public: |
337 PlatformParker() { |
337 PlatformParker() { |
338 int status; |
338 int status; |
339 status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr()); |
339 status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr()); |
340 assert_status(status == 0, status, "cond_init rel"); |
340 assert_status(status == 0, status, "cond_init rel"); |
341 status = pthread_cond_init (&_cond[ABS_INDEX], NULL); |
341 status = pthread_cond_init (&_cond[ABS_INDEX], NULL); |
342 assert_status(status == 0, status, "cond_init abs"); |
342 assert_status(status == 0, status, "cond_init abs"); |
343 status = pthread_mutex_init (_mutex, NULL); |
343 status = pthread_mutex_init (_mutex, NULL); |
344 assert_status(status == 0, status, "mutex_init"); |
344 assert_status(status == 0, status, "mutex_init"); |
345 _cur_index = -1; // mark as unused |
345 _cur_index = -1; // mark as unused |
346 } |
346 } |
347 }; |
347 }; |
348 |
348 |
349 #endif // OS_LINUX_VM_OS_LINUX_HPP |
349 #endif // OS_LINUX_VM_OS_LINUX_HPP |