Skip to content

Commit 8fda88f

Browse files
authored
Add Thread::Local(T) (#15616)
The `@[ThreadLocal]` annotation only works on some targets and doesn't allow registering a destructor callback that will be invoked when a thread shuts down. We currently don't have threads shutting down, but with [RFC 2] it will start happening (at least isolated contexts are expected to shut down, others should eventually evolve to shut down too), or use the complex `Crystal::ThreadLocalValue` to tie a value to a thread, which in turn requires finalize methods [RFC 2]: crystal-lang/rfcs#2
1 parent 1edc082 commit 8fda88f

File tree

32 files changed

+205
-4
lines changed

32 files changed

+205
-4
lines changed

src/crystal/system/thread_local.cr

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class Thread
2+
struct Local(T)
3+
# Reserves space for saving a `T` reference on each thread.
4+
def initialize
5+
{% unless T < Reference || T < Pointer || T.union_types.all? { |t| t == Nil || t < Reference } %}
6+
{% raise "Can only create Thread::Local with reference types, nilable reference types, or pointer types, not {{T}}" %}
7+
{% end %}
8+
end
9+
10+
# Reserves space for saving a `T` reference on each thread and registers a
11+
# destructor that will be called when a thread terminates if the local value
12+
# has been set.
13+
def initialize(&destructor : Proc(T, Nil))
14+
{% unless T < Reference || T < Pointer || T.union_types.all? { |t| t == Nil || t < Reference } %}
15+
{% raise "Can only create Thread::Local with reference types, nilable reference types, or pointer types, not {{T}}" %}
16+
{% end %}
17+
end
18+
19+
# Returns the current local value for the thread; if unset constructs one by
20+
# yielding and sets it as the current local value.
21+
def get(& : -> T) : T
22+
get? || set(yield)
23+
end
24+
25+
# Returns the current local value for the thread or `nil` if there is none.
26+
# def get? : T?
27+
28+
# Sets *value* as the current local value for the thread.
29+
# def set(value : T) : T
30+
end
31+
end
32+
33+
{% if flag?(:wasi) %}
34+
require "./wasi/thread_local"
35+
{% elsif flag?(:unix) %}
36+
require "./unix/thread_local"
37+
{% elsif flag?(:win32) %}
38+
require "./win32/thread_local"
39+
{% else %}
40+
{% raise "Thread not supported" %}
41+
{% end %}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require "c/pthread"
2+
3+
class Thread
4+
struct Local(T)
5+
@key = uninitialized LibC::PthreadKeyT
6+
7+
def initialize
8+
previous_def
9+
@key = pthread_key_create(nil)
10+
end
11+
12+
def initialize(&destructor : Proc(T, Nil))
13+
previous_def(&destructor)
14+
@key = pthread_key_create(destructor.unsafe_as(Proc(Void*, Nil)))
15+
end
16+
17+
private def pthread_key_create(destructor)
18+
err = LibC.pthread_key_create(out key, destructor)
19+
raise RuntimeError.from_os_error("pthread_key_create", Errno.new(err)) unless err == 0
20+
key
21+
end
22+
23+
def get? : T?
24+
pointer = LibC.pthread_getspecific(@key)
25+
pointer.as(T) unless pointer.null?
26+
end
27+
28+
def set(value : T) : T
29+
err = LibC.pthread_setspecific(@key, value.as(Void*))
30+
raise RuntimeError.from_os_error("pthread_setspecific", Errno.new(err)) unless err == 0
31+
value
32+
end
33+
end
34+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Thread
2+
struct Local(T)
3+
@value : T?
4+
5+
def initialize
6+
previous_def
7+
end
8+
9+
def initialize(&destructor : T ->)
10+
previous_def(&destructor)
11+
end
12+
13+
def get? : T?
14+
@value
15+
end
16+
17+
def set(value : T) : T
18+
@value = value
19+
end
20+
end
21+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require "c/fibersapi"
2+
3+
class Thread
4+
struct Local(T)
5+
@key = uninitialized LibC::DWORD
6+
7+
def initialize
8+
previous_def
9+
@key = fls_alloc(nil)
10+
end
11+
12+
def initialize(&destructor : Proc(T, Nil))
13+
previous_def(&destructor)
14+
@key = fls_alloc(destructor.unsafe_as(LibC::FLS_CALLBACK_FUNCTION))
15+
end
16+
17+
private def fls_alloc(destructor)
18+
key = LibC.FlsAlloc(destructor)
19+
raise RuntimeError.from_winerror("FlsAlloc: out of indexes") if key == LibC::FLS_OUT_OF_INDEXES
20+
key
21+
end
22+
23+
def get? : T?
24+
pointer = LibC.FlsGetValue(@key)
25+
pointer.as(T) unless pointer.null?
26+
end
27+
28+
def set(value : T) : T
29+
ret = LibC.FlsSetValue(@key, value.as(T))
30+
raise RuntimeError.from_winerror("FlsSetValue") if ret == 0
31+
value
32+
end
33+
end
34+
end

src/lib_c/aarch64-android/c/pthread.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ lib LibC
2626
fun pthread_getspecific(__key : PthreadKeyT) : Void*
2727
fun pthread_join(__pthread : PthreadT, __return_value_ptr : Void**) : Int
2828
fun pthread_key_create(__key_ptr : PthreadKeyT*, __key_destructor : Void* ->) : Int
29+
fun pthread_key_delete(__key_ptr : PthreadKeyT) : Int
2930

3031
fun pthread_mutexattr_destroy(__attr : PthreadMutexattrT*) : Int
3132
fun pthread_mutexattr_init(__attr : PthreadMutexattrT*) : Int

src/lib_c/aarch64-darwin/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ lib LibC
1313
fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int
1414
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
1515
fun pthread_detach(x0 : PthreadT) : Int
16+
fun pthread_getspecific(PthreadKeyT) : Void*
1617
fun pthread_get_stackaddr_np(x0 : PthreadT) : Void*
1718
fun pthread_get_stacksize_np(x0 : PthreadT) : SizeT
1819
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
20+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
21+
fun pthread_key_delete(PthreadKeyT) : Int
1922
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2023
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2124
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -26,4 +29,5 @@ lib LibC
2629
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
2730
fun pthread_self : PthreadT
2831
fun pthread_setname_np(Char*) : Int
32+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
2933
end

src/lib_c/aarch64-darwin/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ lib LibC
4040
end
4141

4242
type PthreadT = Void*
43+
alias PthreadKeyT = UInt
4344
alias SSizeT = Long
4445
alias SusecondsT = Int
4546
alias TimeT = Long

src/lib_c/aarch64-linux-gnu/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ lib LibC
2525
fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int
2626
fun pthread_detach(th : PthreadT) : Int
2727
fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int
28+
fun pthread_getspecific(PthreadKeyT) : Void*
2829
fun pthread_equal(thread1 : PthreadT, thread2 : PthreadT) : Int
2930
fun pthread_join(th : PthreadT, thread_return : Void**) : Int
31+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
32+
fun pthread_key_delete(PthreadKeyT) : Int
3033
fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int
3134
fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int
3235
fun pthread_mutexattr_settype(attr : PthreadMutexattrT*, type : Int) : Int
@@ -37,4 +40,5 @@ lib LibC
3740
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
3841
fun pthread_self : PthreadT
3942
fun pthread_setname_np(PthreadT, Char*) : Int
43+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
4044
end

src/lib_c/aarch64-linux-gnu/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ lib LibC
4141
end
4242

4343
alias PthreadT = ULong
44+
alias PthreadKeyT = UInt
4445
alias SSizeT = Long
4546
alias SusecondsT = Long
4647
alias TimeT = Long

src/lib_c/aarch64-linux-musl/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ lib LibC
1717
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
1818
fun pthread_detach(x0 : PthreadT) : Int
1919
fun pthread_getattr_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int
20+
fun pthread_getspecific(PthreadKeyT) : Void*
2021
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
22+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
23+
fun pthread_key_delete(PthreadKeyT) : Int
2124
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2225
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2326
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -28,4 +31,5 @@ lib LibC
2831
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
2932
fun pthread_self : PthreadT
3033
fun pthread_setname_np(PthreadT, Char*) : Int
34+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3135
end

src/lib_c/aarch64-linux-musl/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ lib LibC
5454
end
5555

5656
type PthreadT = Void*
57+
alias PthreadKeyT = UInt
5758
alias SSizeT = Long
5859
alias SusecondsT = Long
5960
alias TimeT = Long

src/lib_c/arm-linux-gnueabihf/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ lib LibC
2525
fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int
2626
fun pthread_detach(th : PthreadT) : Int
2727
fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int
28+
fun pthread_getspecific(PthreadKeyT) : Void*
2829
fun pthread_equal(thread1 : PthreadT, thread2 : PthreadT) : Int
2930
fun pthread_join(th : PthreadT, thread_return : Void**) : Int
31+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
32+
fun pthread_key_delete(PthreadKeyT) : Int
3033
fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int
3134
fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int
3235
fun pthread_mutexattr_settype(attr : PthreadMutexattrT*, type : Int) : Int
@@ -37,4 +40,5 @@ lib LibC
3740
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
3841
fun pthread_self : PthreadT
3942
fun pthread_setname_np(PthreadT, Char*) : Int
43+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
4044
end

src/lib_c/arm-linux-gnueabihf/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ lib LibC
5454
end
5555

5656
alias PthreadT = ULong
57+
alias PthreadKeyT = UInt
5758
alias SSizeT = Int
5859
alias SusecondsT = Long
5960
alias TimeT = Long

src/lib_c/i386-linux-gnu/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ lib LibC
2525
fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int
2626
fun pthread_detach(th : PthreadT) : Int
2727
fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int
28+
fun pthread_getspecific(PthreadKeyT) : Void*
2829
fun pthread_join(th : PthreadT, thread_return : Void**) : Int
30+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
31+
fun pthread_key_delete(PthreadKeyT) : Int
2932
fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int
3033
fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int
3134
fun pthread_mutexattr_settype(attr : PthreadMutexattrT*, type : Int) : Int
@@ -36,4 +39,5 @@ lib LibC
3639
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
3740
fun pthread_self : PthreadT
3841
fun pthread_setname_np(PthreadT, Char*) : Int
42+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3943
end

src/lib_c/i386-linux-gnu/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ lib LibC
4141
end
4242

4343
alias PthreadT = ULong
44+
alias PthreadKeyT = UInt
4445
alias SSizeT = Int
4546
alias SusecondsT = Long
4647
alias TimeT = Long

src/lib_c/i386-linux-musl/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ lib LibC
1717
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
1818
fun pthread_detach(x0 : PthreadT) : Int
1919
fun pthread_getattr_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int
20+
fun pthread_getspecific(PthreadKeyT) : Void*
2021
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
22+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
23+
fun pthread_key_delete(PthreadKeyT) : Int
2124
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2225
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2326
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -28,4 +31,5 @@ lib LibC
2831
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
2932
fun pthread_self : PthreadT
3033
fun pthread_setname_np(PthreadT, Char*) : Int
34+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3135
end

src/lib_c/i386-linux-musl/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ lib LibC
5454
end
5555

5656
type PthreadT = Void*
57+
alias PthreadKeyT = UInt
5758
alias SSizeT = Int
5859
alias SusecondsT = Long
5960
alias TimeT = Long

src/lib_c/x86_64-darwin/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ lib LibC
1515
fun pthread_detach(x0 : PthreadT) : Int
1616
fun pthread_get_stackaddr_np(x0 : PthreadT) : Void*
1717
fun pthread_get_stacksize_np(x0 : PthreadT) : SizeT
18+
fun pthread_getspecific(PthreadKeyT) : Void*
1819
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
20+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
21+
fun pthread_key_delete(PthreadKeyT) : Int
1922
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2023
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2124
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -26,4 +29,5 @@ lib LibC
2629
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
2730
fun pthread_self : PthreadT
2831
fun pthread_setname_np(Char*) : Int
32+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
2933
end

src/lib_c/x86_64-darwin/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ lib LibC
4040
end
4141

4242
type PthreadT = Void*
43+
alias PthreadKeyT = UInt
4344
alias SSizeT = Long
4445
alias SusecondsT = Int
4546
alias TimeT = Long

src/lib_c/x86_64-dragonfly/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ lib LibC
1919
fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int
2020
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
2121
fun pthread_detach(x0 : PthreadT) : Int
22+
fun pthread_getspecific(PthreadKeyT) : Void*
2223
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
24+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
25+
fun pthread_key_delete(PthreadKeyT) : Int
2326
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2427
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2528
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -30,4 +33,5 @@ lib LibC
3033
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
3134
fun pthread_self : PthreadT
3235
fun pthread_setname_np(PthreadT, Char*) : Int
36+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3337
end

src/lib_c/x86_64-dragonfly/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib LibC
1717
type PthreadAttrT = Void*
1818
type PthreadCondT = Void*
1919
type PthreadCondattrT = Void*
20+
alias PthreadKeyT = Int
2021
type PthreadMutexT = Void*
2122
type PthreadMutexattrT = Void*
2223
type PthreadT = Void*

src/lib_c/x86_64-freebsd/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ lib LibC
1919
fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int
2020
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
2121
fun pthread_detach(x0 : PthreadT) : Int
22+
fun pthread_getspecific(PthreadKeyT) : Void*
2223
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
24+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
25+
fun pthread_key_delete(PthreadKeyT) : Int
2326
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
2427
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
2528
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
@@ -30,4 +33,5 @@ lib LibC
3033
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
3134
fun pthread_self : PthreadT
3235
fun pthread_set_name_np(PthreadT, Char*)
36+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3337
end

src/lib_c/x86_64-freebsd/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib LibC
1717
type PthreadAttrT = Void*
1818
type PthreadCondT = Void*
1919
type PthreadCondattrT = Void*
20+
alias PthreadKeyT = Int
2021
type PthreadMutexT = Void*
2122
type PthreadMutexattrT = Void*
2223
type PthreadT = Void*

src/lib_c/x86_64-linux-gnu/c/pthread.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ lib LibC
2525
fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int
2626
fun pthread_detach(th : PthreadT) : Int
2727
fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int
28+
fun pthread_getspecific(PthreadKeyT) : Void*
2829
fun pthread_join(th : PthreadT, thread_return : Void**) : Int
30+
fun pthread_key_create(PthreadKeyT*, (Void*) ->) : Int
31+
fun pthread_key_delete(PthreadKeyT) : Int
2932
fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int
3033
fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int
3134
fun pthread_mutexattr_settype(attr : PthreadMutexattrT*, type : Int) : Int
@@ -36,4 +39,5 @@ lib LibC
3639
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
3740
fun pthread_self : PthreadT
3841
fun pthread_setname_np(PthreadT, Char*) : Int
42+
fun pthread_setspecific(PthreadKeyT, Void*) : Int
3943
end

src/lib_c/x86_64-linux-gnu/c/sys/types.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ lib LibC
4040
__align : Int
4141
end
4242

43+
alias PthreadKeyT = UInt
4344
alias PthreadT = ULong
4445
alias SSizeT = Long
4546
alias SusecondsT = Long

0 commit comments

Comments
 (0)