@@ -31,6 +31,11 @@ extern void *_keymgr_get_and_lock_processwide_ptr(unsigned int key);
31
31
extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned int key , void * * result );
32
32
extern int _keymgr_set_lockmode_processwide_ptr (unsigned int key , unsigned int mode );
33
33
34
+ // private dyld3/dyld4 stuff
35
+ extern void _dyld_atfork_prepare (void ) __attribute__((weak_import ));
36
+ extern void _dyld_atfork_parent (void ) __attribute__((weak_import ));
37
+ //extern void _dyld_fork_child(void) __attribute__((weak_import));
38
+
34
39
static void attach_exception_port (thread_port_t thread , int segv_only );
35
40
36
41
// low 16 bits are the thread id, the next 8 bits are the original gc_state
@@ -521,6 +526,28 @@ static kern_return_t profiler_segv_handler
521
526
}
522
527
#endif
523
528
529
+ static int jl_lock_profile_mach (void )
530
+ {
531
+ jl_lock_profile ();
532
+ void * unused = NULL ;
533
+ int keymgr_locked = _keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_DW2_OBJ_LIST , & unused ) == 0 ;
534
+ if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
535
+ _dyld_atfork_prepare ();
536
+ return keymgr_locked ;
537
+ }
538
+
539
+ static void jl_unlock_profile_mach (int keymgr_locked )
540
+ {
541
+ if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
542
+ _dyld_atfork_parent ();
543
+ if (keymgr_locked )
544
+ _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST );
545
+ jl_unlock_profile ();
546
+ }
547
+
548
+ #define jl_lock_profile () int keymgr_locked = jl_lock_profile_mach()
549
+ #define jl_unlock_profile () jl_unlock_profile_mach(keymgr_locked)
550
+
524
551
void * mach_profile_listener (void * arg )
525
552
{
526
553
(void )arg ;
@@ -539,8 +566,6 @@ void *mach_profile_listener(void *arg)
539
566
// sample each thread, round-robin style in reverse order
540
567
// (so that thread zero gets notified last)
541
568
jl_lock_profile ();
542
- void * unused = NULL ;
543
- int keymgr_locked = _keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_DW2_OBJ_LIST , & unused ) == 0 ;
544
569
for (i = jl_n_threads ; i -- > 0 ; ) {
545
570
// if there is no space left, break early
546
571
if (jl_profile_is_buffer_full ()) {
@@ -593,8 +618,6 @@ void *mach_profile_listener(void *arg)
593
618
// We're done! Resume the thread.
594
619
jl_thread_resume (i , 0 );
595
620
}
596
- if (keymgr_locked )
597
- _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST );
598
621
jl_unlock_profile ();
599
622
if (running ) {
600
623
// Reset the alarm
0 commit comments