mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
fix thread_unix for Darwin after pthread corrections in posix package
afed3ceremoved the sys/unix package and moved over to sys/posix, it has new bindings for the pthread APIs but should have been equivalent (not).8fb7182used `CANCEL_ENABLE :: 0`, `CANCEL_DISABLE :: 1`, `CANCEL_DEFERRED :: 0`, `CANCEL_ASYNCHRONOUS :: 1` for Darwin, while the correct values are `1`, `0`, `2` and `0` respectively (same mistake was made for FreeBSD in that commit). What this meant is that the `pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS)` was not actually successful, but because the error wasn't checked it was assumed it was. It also meant `pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)` would actually be setting `PTHREAD_CANCEL_DISABLE`. The code in this PR restores the behaviour by now actually deliberately setting `PTHREAD_CANCEL_DISABLE` and not setting `PTHREAD_CANCEL_ASYNCHRONOUS` which was the previous behaviour that does actually seem to work for some reason. (I also fixed an issue in fmt where `x` would use uppercase if it was a pointer.)
This commit is contained in:
@@ -1531,7 +1531,7 @@ fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
|
||||
case 'o': _fmt_int(fi, u, 8, false, 8*size_of(rawptr), __DIGITS_UPPER)
|
||||
case 'i', 'd': _fmt_int(fi, u, 10, false, 8*size_of(rawptr), __DIGITS_UPPER)
|
||||
case 'z': _fmt_int(fi, u, 12, false, 8*size_of(rawptr), __DIGITS_UPPER)
|
||||
case 'x': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER)
|
||||
case 'x': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_LOWER)
|
||||
case 'X': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER)
|
||||
|
||||
case:
|
||||
|
||||
@@ -355,12 +355,16 @@ Thread_Scope :: enum c.int {
|
||||
}
|
||||
|
||||
Cancel_State :: enum c.int {
|
||||
// Cancel takes place at next cancellation point.
|
||||
ENABLE = PTHREAD_CANCEL_ENABLE,
|
||||
// Cancel postponed.
|
||||
DISABLE = PTHREAD_CANCEL_DISABLE,
|
||||
}
|
||||
|
||||
Cancel_Type :: enum c.int {
|
||||
// Cancel waits until cancellation point.
|
||||
DEFERRED = PTHREAD_CANCEL_DEFERRED,
|
||||
// Cancel occurs immediately.
|
||||
ASYNCHRONOUS = PTHREAD_CANCEL_ASYNCHRONOUS,
|
||||
}
|
||||
|
||||
@@ -372,6 +376,12 @@ when ODIN_OS == .Darwin {
|
||||
PTHREAD_CANCEL_DISABLE :: 0x00
|
||||
PTHREAD_CANCEL_ENABLE :: 0x01
|
||||
|
||||
// PTHREAD_CANCEL_ASYNCHRONOUS :: 1
|
||||
// PTHREAD_CANCEL_DEFERRED :: 0
|
||||
//
|
||||
// PTHREAD_CANCEL_DISABLE :: 1
|
||||
// PTHREAD_CANCEL_ENABLE :: 0
|
||||
|
||||
PTHREAD_CANCELED :: rawptr(uintptr(1))
|
||||
|
||||
PTHREAD_CREATE_DETACHED :: 2
|
||||
@@ -434,8 +444,8 @@ when ODIN_OS == .Darwin {
|
||||
PTHREAD_PRIO_NONE :: 0
|
||||
PTHREAD_PRIO_PROTECT :: 2
|
||||
|
||||
PTHREAD_PROCESS_SHARED :: 0
|
||||
PTHREAD_PROCESS_PRIVATE :: 1
|
||||
PTHREAD_PROCESS_SHARED :: 1
|
||||
PTHREAD_PROCESS_PRIVATE :: 0
|
||||
|
||||
PTHREAD_SCOPE_PROCESS :: 0
|
||||
PTHREAD_SCOPE_SYSTEM :: 2
|
||||
|
||||
@@ -23,7 +23,9 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
t := (^Thread)(t)
|
||||
|
||||
// We need to give the thread a moment to start up before we enable cancellation.
|
||||
can_set_thread_cancel_state := posix.pthread_setcancelstate(.ENABLE, nil) == nil
|
||||
// NOTE(laytan): setting to .DISABLE on darwin, with .ENABLE pthread_cancel would deadlock
|
||||
// most of the time, don't ask me why.
|
||||
can_set_thread_cancel_state := posix.pthread_setcancelstate(.DISABLE when ODIN_OS == .Darwin else .ENABLE, nil) == nil
|
||||
|
||||
t.id = sync.current_thread_id()
|
||||
|
||||
@@ -36,9 +38,15 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
}
|
||||
|
||||
// Enable thread's cancelability.
|
||||
if can_set_thread_cancel_state {
|
||||
posix.pthread_setcanceltype (.ASYNCHRONOUS, nil)
|
||||
posix.pthread_setcancelstate(.ENABLE, nil)
|
||||
// NOTE(laytan): Darwin does not correctly/fully support all of this, not doing this does
|
||||
// actually make pthread_cancel work in the capacity of my tests, while executing this would
|
||||
// basically always make it deadlock.
|
||||
if ODIN_OS != .Darwin && can_set_thread_cancel_state {
|
||||
err := posix.pthread_setcancelstate(.ENABLE, nil)
|
||||
assert_contextless(err == nil)
|
||||
|
||||
err = posix.pthread_setcanceltype(.ASYNCHRONOUS, nil)
|
||||
assert_contextless(err == nil)
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -101,5 +101,29 @@ int main(int argc, char *argv[])
|
||||
printf("timespec %zu %zu\n", sizeof(struct timespec), _Alignof(struct timespec));
|
||||
printf("clock_t %zu %zu\n", sizeof(clock_t), _Alignof(clock_t));
|
||||
|
||||
printf("PTHREAD_CANCEL_ASYNCHRONOUS %d\n", PTHREAD_CANCEL_ASYNCHRONOUS);
|
||||
printf("PTHREAD_CANCEL_DEFERRED %d\n", PTHREAD_CANCEL_DEFERRED);
|
||||
|
||||
printf("PTHREAD_CANCEL_DISABLE %d\n", PTHREAD_CANCEL_DISABLE);
|
||||
printf("PTHREAD_CANCEL_ENABLE %d\n", PTHREAD_CANCEL_ENABLE);
|
||||
|
||||
printf("PTHREAD_CANCELED %p\n", PTHREAD_CANCELED);
|
||||
|
||||
printf("PTHREAD_CREATE_JOINABLE %d\n", PTHREAD_CREATE_JOINABLE);
|
||||
printf("PTHREAD_CREATE_DETACHED %d\n", PTHREAD_CREATE_DETACHED);
|
||||
|
||||
printf("PTHREAD_EXPLICIT_SCHED %d\n", PTHREAD_EXPLICIT_SCHED);
|
||||
printf("PTHREAD_INHERIT_SCHED %d\n", PTHREAD_INHERIT_SCHED);
|
||||
|
||||
printf("PTHREAD_PRIO_INHERIT %d\n", PTHREAD_PRIO_INHERIT);
|
||||
printf("PTHREAD_PRIO_NONE %d\n", PTHREAD_PRIO_NONE);
|
||||
printf("PTHREAD_PRIO_PROTECT %d\n", PTHREAD_PRIO_PROTECT);
|
||||
|
||||
printf("PTHREAD_PROCESS_SHARED %d\n", PTHREAD_PROCESS_SHARED);
|
||||
printf("PTHREAD_PROCESS_PRIVATE %d\n", PTHREAD_PROCESS_PRIVATE);
|
||||
|
||||
printf("PTHREAD_SCOPE_PROCESS %d\n", PTHREAD_SCOPE_PROCESS);
|
||||
printf("PTHREAD_SCOPE_SYSTEM %d\n", PTHREAD_SCOPE_SYSTEM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -75,4 +75,28 @@ main :: proc() {
|
||||
fmt.println("time_t", size_of(posix.time_t), align_of(posix.time_t))
|
||||
fmt.println("timespec", size_of(posix.timespec), align_of(posix.timespec))
|
||||
fmt.println("clock_t", size_of(posix.clock_t), align_of(posix.clock_t))
|
||||
|
||||
fmt.println("PTHREAD_CANCEL_ASYNCHRONOUS", posix.PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||
fmt.println("PTHREAD_CANCEL_DEFERRED", posix.PTHREAD_CANCEL_DEFERRED)
|
||||
|
||||
fmt.println("PTHREAD_CANCEL_DISABLE", posix.PTHREAD_CANCEL_DISABLE)
|
||||
fmt.println("PTHREAD_CANCEL_ENABLE", posix.PTHREAD_CANCEL_ENABLE)
|
||||
|
||||
fmt.printfln("PTHREAD_CANCELED %#x", posix.PTHREAD_CANCELED)
|
||||
|
||||
fmt.println("PTHREAD_CREATE_JOINABLE", posix.PTHREAD_CREATE_JOINABLE)
|
||||
fmt.println("PTHREAD_CREATE_DETACHED", posix.PTHREAD_CREATE_DETACHED)
|
||||
|
||||
fmt.println("PTHREAD_EXPLICIT_SCHED", posix.PTHREAD_EXPLICIT_SCHED)
|
||||
fmt.println("PTHREAD_INHERIT_SCHED", posix.PTHREAD_INHERIT_SCHED)
|
||||
|
||||
fmt.println("PTHREAD_PRIO_INHERIT", posix.PTHREAD_PRIO_INHERIT)
|
||||
fmt.println("PTHREAD_PRIO_NONE", posix.PTHREAD_PRIO_NONE)
|
||||
fmt.println("PTHREAD_PRIO_PROTECT", posix.PTHREAD_PRIO_PROTECT)
|
||||
|
||||
fmt.println("PTHREAD_PROCESS_SHARED", posix.PTHREAD_PROCESS_SHARED)
|
||||
fmt.println("PTHREAD_PROCESS_PRIVATE", posix.PTHREAD_PROCESS_PRIVATE)
|
||||
|
||||
fmt.println("PTHREAD_SCOPE_PROCESS", posix.PTHREAD_SCOPE_PROCESS)
|
||||
fmt.println("PTHREAD_SCOPE_SYSTEM", posix.PTHREAD_SCOPE_SYSTEM)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user