2 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
12 #include <libroot_private.h>
13 #include <pthread_private.h>
14 #include <runtime_loader.h>
15 #include <thread_defs.h>
21 // thread_entry is still defined in OS.h for compatibility reasons
24 typedef struct callback_node
{
25 struct callback_node
*next
;
26 void (*function
)(void *);
31 void _thread_do_exit_work(void);
32 void _thread_do_exit_notification(void);
36 thread_entry(void* _entry
, void* _thread
)
38 thread_func entry
= (thread_func
)_entry
;
39 pthread_thread
* thread
= (pthread_thread
*)_thread
;
42 returnCode
= entry(thread
->entry_argument
);
44 _thread_do_exit_work();
51 _thread_do_exit_notification(void)
53 // empty stub for R5 compatibility
58 _thread_do_exit_work(void)
60 callback_node
*node
= tls_get(TLS_ON_EXIT_THREAD_SLOT
);
63 while (node
!= NULL
) {
66 node
->function(node
->argument
);
72 tls_set(TLS_ON_EXIT_THREAD_SLOT
, NULL
);
74 __gRuntimeLoader
->destroy_thread_tls();
76 __pthread_destroy_thread();
81 __set_stack_protection(void)
83 if (__gABIVersion
< B_HAIKU_ABI_GCC_2_HAIKU
) {
87 while (get_next_area_info(B_CURRENT_TEAM
, &cookie
, &info
) == B_OK
) {
88 if ((info
.protection
& B_STACK_AREA
) != 0) {
89 _kern_set_area_protection(info
.area
,
90 B_READ_AREA
| B_WRITE_AREA
| B_EXECUTE_AREA
| B_STACK_AREA
);
101 spawn_thread(thread_func entry
, const char *name
, int32 priority
, void *data
)
103 struct thread_creation_attributes attributes
;
104 pthread_thread
* thread
;
107 thread
= __allocate_pthread(NULL
, data
);
111 _single_threaded
= false;
112 // used for I/O locking - BeOS compatibility issue
114 __pthread_init_creation_attributes(NULL
, thread
, &thread_entry
, entry
,
115 thread
, name
, &attributes
);
116 thread
->flags
|= THREAD_DETACHED
;
118 attributes
.priority
= priority
;
120 id
= _kern_spawn_thread(&attributes
);
125 __set_stack_protection();
133 kill_thread(thread_id thread
)
135 return _kern_kill_thread(thread
);
140 resume_thread(thread_id thread
)
142 return _kern_resume_thread(thread
);
147 suspend_thread(thread_id thread
)
149 return _kern_suspend_thread(thread
);
154 rename_thread(thread_id thread
, const char *name
)
156 return _kern_rename_thread(thread
, name
);
161 set_thread_priority(thread_id thread
, int32 priority
)
163 return _kern_set_thread_priority(thread
, priority
);
168 exit_thread(status_t status
)
170 _thread_do_exit_work();
171 _kern_exit_thread(status
);
176 wait_for_thread(thread_id thread
, status_t
*_returnCode
)
178 return _kern_wait_for_thread(thread
, _returnCode
);
183 on_exit_thread(void (*callback
)(void *), void *data
)
185 callback_node
**head
= (callback_node
**)tls_address(TLS_ON_EXIT_THREAD_SLOT
);
187 callback_node
*node
= malloc(sizeof(callback_node
));
191 node
->function
= callback
;
192 node
->argument
= data
;
194 // add this node to the list
203 _get_thread_info(thread_id thread
, thread_info
*info
, size_t size
)
205 if (info
== NULL
|| size
!= sizeof(thread_info
))
208 return _kern_get_thread_info(thread
, info
);
213 _get_next_thread_info(team_id team
, int32
*cookie
, thread_info
*info
, size_t size
)
215 if (info
== NULL
|| size
!= sizeof(thread_info
))
218 return _kern_get_next_thread_info(team
, cookie
, info
);
223 send_data(thread_id thread
, int32 code
, const void *buffer
, size_t bufferSize
)
225 return _kern_send_data(thread
, code
, buffer
, bufferSize
);
230 receive_data(thread_id
*_sender
, void *buffer
, size_t bufferSize
)
232 return _kern_receive_data(_sender
, buffer
, bufferSize
);
237 has_data(thread_id thread
)
239 return _kern_has_data(thread
);
244 snooze_etc(bigtime_t timeout
, int timeBase
, uint32 flags
)
246 return _kern_snooze_etc(timeout
, timeBase
, flags
, NULL
);
251 snooze(bigtime_t timeout
)
253 return _kern_snooze_etc(timeout
, B_SYSTEM_TIMEBASE
, B_RELATIVE_TIMEOUT
,
259 snooze_until(bigtime_t timeout
, int timeBase
)
261 return _kern_snooze_etc(timeout
, timeBase
, B_ABSOLUTE_TIMEOUT
, NULL
);