]>
Commit | Line | Data |
---|---|---|
33574c17 | 1 | /* Deallocate the kernel thread resources. Mach version. |
dff8da6b | 2 | Copyright (C) 2000-2024 Free Software Foundation, Inc. |
33574c17 ST |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
ad2b41bf ST |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
33574c17 ST |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
ad2b41bf | 13 | Lesser General Public License for more details. |
33574c17 | 14 | |
ad2b41bf ST |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
33574c17 ST |
18 | |
19 | #include <assert.h> | |
20 | #include <errno.h> | |
21 | #include <mach.h> | |
22 | ||
23 | #include <mach/mig_support.h> | |
24 | ||
25 | #include <pt-internal.h> | |
26 | ||
27 | /* Terminate the kernel thread associated with THREAD, and deallocate its | |
28 | right reference and its stack. The function also drops a reference | |
29 | on THREAD. */ | |
30 | void | |
31 | __pthread_thread_terminate (struct __pthread *thread) | |
32 | { | |
33 | thread_t kernel_thread, self_ktid; | |
34 | mach_port_t wakeup_port, reply_port; | |
35 | void *stackaddr; | |
36 | size_t stacksize; | |
37 | error_t err; | |
8c86ba44 | 38 | int self; |
33574c17 ST |
39 | |
40 | kernel_thread = thread->kernel_thread; | |
41 | ||
42 | if (thread->stack) | |
43 | { | |
44 | stackaddr = thread->stackaddr; | |
45 | stacksize = ((thread->guardsize + __vm_page_size - 1) | |
46 | / __vm_page_size) * __vm_page_size + thread->stacksize; | |
47 | } | |
48 | else | |
49 | { | |
50 | stackaddr = NULL; | |
51 | stacksize = 0; | |
52 | } | |
53 | ||
54 | wakeup_port = thread->wakeupmsg.msgh_remote_port; | |
55 | ||
33574c17 | 56 | self_ktid = __mach_thread_self (); |
8c86ba44 | 57 | self = self_ktid == kernel_thread; |
33574c17 ST |
58 | __mach_port_deallocate (__mach_task_self (), self_ktid); |
59 | ||
c1105e34 ST |
60 | /* The kernel thread won't be there any more. */ |
61 | thread->kernel_thread = MACH_PORT_DEAD; | |
62 | ||
8c86ba44 | 63 | /* Release thread resources. */ |
33574c17 ST |
64 | __pthread_dealloc (thread); |
65 | ||
8c86ba44 ST |
66 | /* The wake up port (needed for locks in __pthread_dealloc) is now no longer |
67 | needed. */ | |
33574c17 ST |
68 | __mach_port_destroy (__mach_task_self (), wakeup_port); |
69 | ||
8c86ba44 ST |
70 | /* Each thread has its own reply port, allocated from MiG stub code calling |
71 | __mig_get_reply_port. Destroying it is a bit tricky because the calls | |
72 | involved are also RPCs, causing the creation of a new reply port if | |
73 | currently null. The __thread_terminate_release call is actually a one way | |
74 | simple routine designed not to require a reply port. */ | |
75 | reply_port = self ? __mig_get_reply_port () : MACH_PORT_NULL; | |
76 | /* From here we shall not use a MIG reply port any more. */ | |
77 | ||
78 | /* Finally done with the thread structure (we still needed it to access the | |
79 | reply port). */ | |
80 | __pthread_dealloc_finish (thread); | |
81 | ||
33574c17 ST |
82 | /* Terminate and release all that's left. */ |
83 | err = __thread_terminate_release (kernel_thread, mach_task_self (), | |
84 | kernel_thread, reply_port, | |
85 | (vm_address_t) stackaddr, stacksize); | |
86 | ||
87 | /* The kernel does not support it yet. Leak but at least terminate | |
88 | correctly. */ | |
89 | err = __thread_terminate (kernel_thread); | |
90 | ||
91 | /* We are out of luck. */ | |
92 | assert_perror (err); | |
93 | } |