1593 |
|
|
1594 |
#endif /* PARALLEL_MARK */ |
#endif /* PARALLEL_MARK */ |
1595 |
|
|
1596 |
|
/* |
1597 |
|
* Register a thread that was not created by the gc routines. |
1598 |
|
* Thread was created either by a third party library or a timer or ... |
1599 |
|
*/ |
1600 |
|
static void |
1601 |
|
GC_register_current_thread(pthread_t my_pthread) |
1602 |
|
{ |
1603 |
|
|
1604 |
|
int dummy; |
1605 |
|
GC_thread me; |
1606 |
|
|
1607 |
|
# ifdef DEBUG_THREADS |
1608 |
|
GC_printf1("Registering thread 0x%lx\n", my_pthread); |
1609 |
|
GC_printf1("pid = %ld\n", (long) getpid()); |
1610 |
|
# endif |
1611 |
|
LOCK(); |
1612 |
|
GC_in_thread_creation = TRUE; |
1613 |
|
me = GC_new_thread(my_pthread); |
1614 |
|
GC_in_thread_creation = FALSE; |
1615 |
|
#ifdef GC_DARWIN_THREADS |
1616 |
|
me -> stop_info.mach_thread = mach_thread_self(); |
1617 |
|
#else |
1618 |
|
me -> stop_info.stack_ptr = 0; |
1619 |
|
#endif |
1620 |
|
me -> flags = DETACHED; |
1621 |
|
/* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */ |
1622 |
|
/* doesn't work because the stack base in /proc/self/stat is the */ |
1623 |
|
/* one for the main thread. There is a strong argument that that's */ |
1624 |
|
/* a kernel bug, but a pervasive one. */ |
1625 |
|
# ifdef STACK_GROWS_DOWN |
1626 |
|
me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1)) |
1627 |
|
& ~(GC_page_size - 1)); |
1628 |
|
# ifndef GC_DARWIN_THREADS |
1629 |
|
me -> stop_info.stack_ptr = me -> stack_end - 0x10; |
1630 |
|
# endif |
1631 |
|
/* Needs to be plausible, since an asynchronous stack mark */ |
1632 |
|
/* should not crash. */ |
1633 |
|
# else |
1634 |
|
me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1)); |
1635 |
|
me -> stop_info.stack_ptr = me -> stack_end + 0x10; |
1636 |
|
# endif |
1637 |
|
/* This is dubious, since we may be more than a page into the stack, */ |
1638 |
|
/* and hence skip some of it, though it's not clear that matters. */ |
1639 |
|
# ifdef IA64 |
1640 |
|
me -> backing_store_end = (ptr_t) |
1641 |
|
(GC_save_regs_in_stack() & ~(GC_page_size - 1)); |
1642 |
|
/* This is also < 100% convincing. We should also read this */ |
1643 |
|
/* from /proc, but the hook to do so isn't there yet. */ |
1644 |
|
# endif /* IA64 */ |
1645 |
|
GC_init_thread_local(me); |
1646 |
|
UNLOCK(); |
1647 |
|
} |
1648 |
|
|
1649 |
|
/* |
1650 |
|
* Run a function under gc control in a thread not created by the gc. |
1651 |
|
*/ |
1652 |
|
GC_API void * |
1653 |
|
GC_run_thread(void *(*thread_func)(void *), void *arg) |
1654 |
|
{ |
1655 |
|
pthread_t my_pthread; |
1656 |
|
void *result = 0; |
1657 |
|
|
1658 |
|
my_pthread = pthread_self(); |
1659 |
|
GC_register_current_thread(my_pthread); |
1660 |
|
pthread_cleanup_push(GC_thread_exit_proc, 0); |
1661 |
|
result = (*thread_func)(arg); |
1662 |
|
pthread_cleanup_pop(1); |
1663 |
|
return result; |
1664 |
|
} |
1665 |
|
|
1666 |
# endif /* GC_LINUX_THREADS and friends */ |
# endif /* GC_LINUX_THREADS and friends */ |
1667 |
|
|