232 PlatformParker(); |
232 PlatformParker(); |
233 }; |
233 }; |
234 |
234 |
235 // Workaround for a bug in macOSX kernel's pthread support (fixed in Mojave?). |
235 // Workaround for a bug in macOSX kernel's pthread support (fixed in Mojave?). |
236 // Avoid ever allocating a pthread_mutex_t at the same address as one of our |
236 // Avoid ever allocating a pthread_mutex_t at the same address as one of our |
237 // former pthread_cond_t, by using a freelist of mutex/condvar pairs. |
237 // former pthread_cond_t, by using freelists of mutexes and condvars. |
238 // Conditional to avoid extra indirection and padding loss on other platforms. |
238 // Conditional to avoid extra indirection and padding loss on other platforms. |
239 #ifdef __APPLE__ |
239 #ifdef __APPLE__ |
240 #define PLATFORM_MONITOR_IMPL_INDIRECT 1 |
240 #define PLATFORM_MONITOR_IMPL_INDIRECT 1 |
241 #else |
241 #else |
242 #define PLATFORM_MONITOR_IMPL_INDIRECT 0 |
242 #define PLATFORM_MONITOR_IMPL_INDIRECT 0 |
243 #endif |
243 #endif |
244 |
244 |
245 // Platform specific implementation that underpins VM Monitor/Mutex class |
245 // Platform specific implementations that underpin VM Mutex/Monitor classes |
246 class PlatformMonitor : public CHeapObj<mtSynchronizer> { |
246 |
247 class Impl : public CHeapObj<mtSynchronizer> { |
247 class PlatformMutex : public CHeapObj<mtSynchronizer> { |
248 public: |
248 #if PLATFORM_MONITOR_IMPL_INDIRECT |
|
249 class Mutex : public CHeapObj<mtSynchronizer> { |
|
250 public: |
249 pthread_mutex_t _mutex; |
251 pthread_mutex_t _mutex; |
250 pthread_cond_t _cond; |
252 Mutex* _next; |
251 Impl* _next; |
253 |
252 |
254 Mutex(); |
253 Impl(); |
255 ~Mutex(); |
254 ~Impl(); |
|
255 }; |
256 }; |
256 |
257 |
257 #if PLATFORM_MONITOR_IMPL_INDIRECT |
258 Mutex* _impl; |
258 |
259 |
259 Impl* _impl; |
260 static pthread_mutex_t _freelist_lock; // used for mutex and cond freelists |
260 |
261 static Mutex* _mutex_freelist; |
|
262 |
|
263 protected: |
|
264 class WithFreeListLocked; |
261 pthread_mutex_t* mutex() { return &(_impl->_mutex); } |
265 pthread_mutex_t* mutex() { return &(_impl->_mutex); } |
262 pthread_cond_t* cond() { return &(_impl->_cond); } |
266 |
263 |
267 public: |
264 class WithFreeListLocked; |
268 PlatformMutex(); // Use freelist allocation of impl. |
265 static pthread_mutex_t _freelist_lock; |
269 ~PlatformMutex(); |
266 static Impl* _freelist; |
|
267 |
|
268 public: |
|
269 PlatformMonitor(); // Use freelist allocation of impl. |
|
270 ~PlatformMonitor(); |
|
271 |
270 |
272 static void init(); // Initialize the freelist. |
271 static void init(); // Initialize the freelist. |
273 |
272 |
274 #else |
273 #else |
275 |
274 |
276 Impl _impl; |
275 pthread_mutex_t _mutex; |
277 |
276 |
278 pthread_mutex_t* mutex() { return &(_impl._mutex); } |
277 protected: |
279 pthread_cond_t* cond() { return &(_impl._cond); } |
278 pthread_mutex_t* mutex() { return &_mutex; } |
280 |
279 |
281 public: |
280 public: |
282 static void init() {} // Nothing needed for the non-indirect case. |
281 static void init() {} // Nothing needed for the non-indirect case. |
283 |
282 |
284 // Default constructor and destructor. |
283 PlatformMutex(); |
|
284 ~PlatformMutex(); |
285 |
285 |
286 #endif // PLATFORM_MONITOR_IMPL_INDIRECT |
286 #endif // PLATFORM_MONITOR_IMPL_INDIRECT |
|
287 |
|
288 private: |
|
289 // Disable copying |
|
290 PlatformMutex(const PlatformMutex&); |
|
291 PlatformMutex& operator=(const PlatformMutex&); |
287 |
292 |
288 public: |
293 public: |
289 void lock(); |
294 void lock(); |
290 void unlock(); |
295 void unlock(); |
291 bool try_lock(); |
296 bool try_lock(); |
|
297 }; |
|
298 |
|
299 class PlatformMonitor : public PlatformMutex { |
|
300 #if PLATFORM_MONITOR_IMPL_INDIRECT |
|
301 class Cond : public CHeapObj<mtSynchronizer> { |
|
302 public: |
|
303 pthread_cond_t _cond; |
|
304 Cond* _next; |
|
305 |
|
306 Cond(); |
|
307 ~Cond(); |
|
308 }; |
|
309 |
|
310 Cond* _impl; |
|
311 |
|
312 static Cond* _cond_freelist; |
|
313 |
|
314 pthread_cond_t* cond() { return &(_impl->_cond); } |
|
315 |
|
316 public: |
|
317 PlatformMonitor(); // Use freelist allocation of impl. |
|
318 ~PlatformMonitor(); |
|
319 |
|
320 #else |
|
321 |
|
322 pthread_cond_t _cond; |
|
323 pthread_cond_t* cond() { return &_cond; } |
|
324 |
|
325 public: |
|
326 PlatformMonitor(); |
|
327 ~PlatformMonitor(); |
|
328 |
|
329 #endif // PLATFORM_MONITOR_IMPL_INDIRECT |
|
330 |
|
331 private: |
|
332 // Disable copying |
|
333 PlatformMonitor(const PlatformMonitor&); |
|
334 PlatformMonitor& operator=(const PlatformMonitor&); |
|
335 |
|
336 public: |
292 int wait(jlong millis); |
337 int wait(jlong millis); |
293 void notify(); |
338 void notify(); |
294 void notify_all(); |
339 void notify_all(); |
295 }; |
340 }; |
296 |
341 |