diff --git a/c/pthread/generated_native_darwin_arm64_llgo_test.go b/c/pthread/generated_native_darwin_arm64_llgo_test.go new file mode 100644 index 00000000..88df7c95 --- /dev/null +++ b/c/pthread/generated_native_darwin_arm64_llgo_test.go @@ -0,0 +1,14 @@ +//go:build llgo && darwin && arm64 && !ios + +package pthread_test + +import ( + "github.com/goplus/lib/c" + "github.com/goplus/lib/c/pthread" + "unsafe" +) + +// nativeJoin follows the platform-specific method/global shape emitted for pthread_t. +func nativeJoin(thread pthread.Thread, result *unsafe.Pointer) c.Int { + return thread.NativeJoin(result) +} diff --git a/c/pthread/generated_native_linux_llgo_test.go b/c/pthread/generated_native_linux_llgo_test.go new file mode 100644 index 00000000..844a2615 --- /dev/null +++ b/c/pthread/generated_native_linux_llgo_test.go @@ -0,0 +1,14 @@ +//go:build llgo && linux && (amd64 || arm64) && !android + +package pthread_test + +import ( + "github.com/goplus/lib/c" + "github.com/goplus/lib/c/pthread" + "unsafe" +) + +// nativeJoin follows the platform-specific method/global shape emitted for pthread_t. +func nativeJoin(thread pthread.Thread, result *unsafe.Pointer) c.Int { + return pthread.NativeJoin(thread, result) +} diff --git a/c/pthread/generated_native_llgo_test.go b/c/pthread/generated_native_llgo_test.go new file mode 100644 index 00000000..8e4e1d33 --- /dev/null +++ b/c/pthread/generated_native_llgo_test.go @@ -0,0 +1,109 @@ +//go:build llgo && ((darwin && arm64 && !ios) || (linux && (amd64 || arm64) && !android)) + +package pthread_test + +import ( + "github.com/goplus/lib/c" + "github.com/goplus/lib/c/pthread" + "runtime" + "testing" + "unsafe" +) + +func TestGeneratedThreadAttributeLayout(t *testing.T) { + size := uintptr(64) + keySize := uintptr(4) + if runtime.GOOS == "linux" && runtime.GOARCH == "amd64" { + size = 56 + } + if runtime.GOOS == "darwin" { + keySize = 8 + } + var attr pthread.Attr + var key pthread.Key + if unsafe.Sizeof(attr) != size || unsafe.Alignof(attr) != 8 { + t.Fatalf("pthread_attr_t = %d/%d, want %d/8", unsafe.Sizeof(attr), unsafe.Alignof(attr), size) + } + if unsafe.Sizeof(key) != keySize { + t.Fatalf("pthread_key_t = %d, want %d", unsafe.Sizeof(key), keySize) + } +} +func TestGeneratedThreadAttributes(t *testing.T) { + t.Run("thread local storage", func(t *testing.T) { + var key pthread.Key + if result := key.Create(nil); result != 0 { + t.Fatalf("pthread_key_create = %d", result) + } + defer func() { + if result := key.Delete(); result != 0 { + t.Errorf("pthread_key_delete = %d", result) + } + }() + if got := key.Get(); got != nil { + t.Fatalf("pthread_getspecific initial value = %p, want nil", got) + } + var value c.Int = 123 + expected := unsafe.Pointer(&value) + if result := key.Set(expected); result != 0 { + t.Fatalf("pthread_setspecific = %d", result) + } + if got := key.Get(); got != expected { + t.Fatalf("pthread_getspecific = %p, want %p", got, expected) + } + if result := key.Set(nil); result != 0 { + t.Fatalf("pthread_setspecific reset = %d", result) + } + }) + var probe struct { + before [8]byte + attr pthread.Attr + after [8]byte + } + for i := range probe.before { + probe.before[i] = 0xa5 + probe.after[i] = 0xa5 + } + if result := probe.attr.Init(); result != 0 { + t.Fatalf("attr_init = %d", result) + } + defer func() { + if result := probe.attr.Destroy(); result != 0 { + t.Errorf("attr_destroy = %d", result) + } + }() + var size c.SizeT + if result := probe.attr.GetStackSize(&size); result != 0 || size == 0 { + t.Fatalf("attr_getstacksize = %d, value %d", result, size) + } + const requested = 1 << 20 + if result := probe.attr.SetStackSize(requested); result != 0 { + t.Fatalf("attr_setstacksize = %d", result) + } + if result := probe.attr.GetStackSize(&size); result != 0 || size != requested { + t.Fatalf("stack size = %d, result %d", size, result) + } + for i := range probe.before { + if probe.before[i] != 0xa5 || probe.after[i] != 0xa5 { + t.Fatal("attribute operation overwrote a buffer boundary") + } + } +} + +//llgo:type C +type nativeThreadStart func(unsafe.Pointer) unsafe.Pointer + +func TestGeneratedNativeThreadRoundtrip(t *testing.T) { + var thread pthread.Thread + var marker uintptr = 123 + start := nativeThreadStart(func(argument unsafe.Pointer) unsafe.Pointer { return argument }) + if result := pthread.NativeCreate(&thread, nil, start, unsafe.Pointer(&marker)); result != 0 { + t.Fatalf("pthread_create = %d", result) + } + var returned unsafe.Pointer + if result := nativeJoin(thread, &returned); result != 0 { + t.Fatalf("pthread_join = %d", result) + } + if returned != unsafe.Pointer(&marker) { + t.Fatalf("thread result = %p, want %p", returned, &marker) + } +} diff --git a/c/pthread/legacy_functions_other.go b/c/pthread/legacy_functions_other.go new file mode 100644 index 00000000..49fb2353 --- /dev/null +++ b/c/pthread/legacy_functions_other.go @@ -0,0 +1,62 @@ +//go:build !windows && !((darwin && arm64 && !ios) || (linux && (amd64 || arm64) && !android)) + +package pthread + +import ( + "github.com/goplus/lib/c" + _ "unsafe" +) + +// The pthread_exit() function terminates the calling thread and +// returns a value via retval that (if the thread is joinable) is +// available to another thread in the same process that calls +// pthread_join(3). +// +// See https://man7.org/linux/man-pages/man3/pthread_exit.3.html +// +//go:linkname Exit C.pthread_exit +func Exit(retval c.Pointer) + +// The pthread_cancel() function sends a cancelation request to the +// thread thread. +// +// See https://man7.org/linux/man-pages/man3/pthread_cancel.3.html +// +//go:linkname Cancel C.pthread_cancel +func Cancel(thread Thread) c.Int + +// llgo:link (*Attr).Init C.pthread_attr_init +func (attr *Attr) Init() c.Int { return 0 } + +// llgo:link (*Attr).Destroy C.pthread_attr_destroy +func (attr *Attr) Destroy() c.Int { return 0 } + +// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate +func (attr *Attr) GetDetached(detached *c.Int) c.Int { return 0 } + +// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate +func (attr *Attr) SetDetached(detached c.Int) c.Int { return 0 } + +// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize +func (attr *Attr) GetStackSize(stackSize *uintptr) c.Int { return 0 } + +// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize +func (attr *Attr) SetStackSize(stackSize uintptr) c.Int { return 0 } + +// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr +func (attr *Attr) GetStackAddr(stackAddr *c.Pointer) c.Int { return 0 } + +// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr +func (attr *Attr) SetStackAddr(stackAddr c.Pointer) c.Int { return 0 } + +// llgo:link (*Key).Create C.pthread_key_create +func (key *Key) Create(destructor func(c.Pointer)) c.Int { return 0 } + +// llgo:link Key.Delete C.pthread_key_delete +func (key Key) Delete() c.Int { return 0 } + +// llgo:link Key.Get C.pthread_getspecific +func (key Key) Get() c.Pointer { return nil } + +// llgo:link Key.Set C.pthread_setspecific +func (key Key) Set(value c.Pointer) c.Int { return __noop__() } diff --git a/c/pthread/libc_darwin_arm64.go b/c/pthread/libc_darwin_arm64.go new file mode 100644 index 00000000..d32b32fe --- /dev/null +++ b/c/pthread/libc_darwin_arm64.go @@ -0,0 +1,691 @@ +//go:build darwin && arm64 && !ios + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package pthread + +import ( + "github.com/goplus/lib/c" + llos "github.com/goplus/lib/c/os" + "unsafe" +) + +// POSIX scheduling policies +const ( + SCHED_OTHER = 1 + SCHED_FIFO = 4 + SCHED_RR = 2 +) + +type OverrideS struct { +} + +type OverrideT = *OverrideS + +// ! +// @function pthread_attr_set_qos_class_np +// +// @abstract +// Sets the QOS class and relative priority of a pthread attribute structure +// which may be used to specify the requested QOS class of newly created +// threads. +// +// @discussion +// The QOS class and relative priority represent an overall combination of +// system quality of service attributes on a thread. +// +// Subsequent calls to interfaces such as pthread_attr_setschedparam() that are +// incompatible or in conflict with the QOS class system will unset the QOS +// class requested with this interface and pthread_attr_get_qos_class_np() will +// return QOS_CLASS_UNSPECIFIED. +// +// @param __attr +// The pthread attribute structure to modify. +// +// @param __qos_class +// A QOS class value: +// - QOS_CLASS_USER_INTERACTIVE +// - QOS_CLASS_USER_INITIATED +// - QOS_CLASS_DEFAULT +// - QOS_CLASS_UTILITY +// - QOS_CLASS_BACKGROUND +// +// EINVAL will be returned if any other value is provided. +// +// @param __relative_priority +// A relative priority within the QOS class. This value is a negative offset +// from the maximum supported scheduler priority for the given class. +// EINVAL will be returned if the value is greater than zero or less than +// QOS_MIN_RELATIVE_PRIORITY. +// +// @return +// Zero if successful, otherwise an errno value. +// +// llgo:link (*Attr).SetQosClassNp C.pthread_attr_set_qos_class_np +func (self *Attr) SetQosClassNp(__qos_class c.Uint, __relative_priority c.Int) c.Int { + return 0 +} + +// ! +// @function pthread_attr_get_qos_class_np +// +// @abstract +// Gets the QOS class and relative priority of a pthread attribute structure. +// +// @param __attr +// The pthread attribute structure to inspect. +// +// @param __qos_class +// On output, a QOS class value: +// - QOS_CLASS_USER_INTERACTIVE +// - QOS_CLASS_USER_INITIATED +// - QOS_CLASS_DEFAULT +// - QOS_CLASS_UTILITY +// - QOS_CLASS_BACKGROUND +// - QOS_CLASS_UNSPECIFIED +// +// This value may be NULL in which case no value is returned. +// +// @param __relative_priority +// On output, a relative priority offset within the QOS class. +// This value may be NULL in which case no value is returned. +// +// @return +// Zero if successful, otherwise an errno value. +// +// llgo:link (*Attr).GetQosClassNp C.pthread_attr_get_qos_class_np +func (self *Attr) GetQosClassNp(__qos_class *c.Uint, __relative_priority *c.Int) c.Int { + return 0 +} + +// ! +// @function pthread_set_qos_class_self_np +// +// @abstract +// Sets the requested QOS class and relative priority of the current thread. +// +// @discussion +// The QOS class and relative priority represent an overall combination of +// system quality of service attributes on a thread. +// +// Subsequent calls to interfaces such as pthread_setschedparam() that are +// incompatible or in conflict with the QOS class system will unset the QOS +// class requested with this interface and pthread_get_qos_class_np() will +// return QOS_CLASS_UNSPECIFIED thereafter. A thread so modified is permanently +// opted-out of the QOS class system and calls to this function to request a QOS +// class for such a thread will fail and return EPERM. +// +// @param __qos_class +// A QOS class value: +// - QOS_CLASS_USER_INTERACTIVE +// - QOS_CLASS_USER_INITIATED +// - QOS_CLASS_DEFAULT +// - QOS_CLASS_UTILITY +// - QOS_CLASS_BACKGROUND +// +// EINVAL will be returned if any other value is provided. +// +// @param __relative_priority +// A relative priority within the QOS class. This value is a negative offset +// from the maximum supported scheduler priority for the given class. +// EINVAL will be returned if the value is greater than zero or less than +// QOS_MIN_RELATIVE_PRIORITY. +// +// @return +// Zero if successful, otherwise an errno value. +// +//go:linkname SetQosClassSelfNp C.pthread_set_qos_class_self_np +func SetQosClassSelfNp(__qos_class c.Uint, __relative_priority c.Int) c.Int + +// ! +// @function pthread_get_qos_class_np +// +// @abstract +// Gets the requested QOS class and relative priority of a thread. +// +// @param __pthread +// The target thread to inspect. +// +// @param __qos_class +// On output, a QOS class value: +// - QOS_CLASS_USER_INTERACTIVE +// - QOS_CLASS_USER_INITIATED +// - QOS_CLASS_DEFAULT +// - QOS_CLASS_UTILITY +// - QOS_CLASS_BACKGROUND +// - QOS_CLASS_UNSPECIFIED +// +// This value may be NULL in which case no value is returned. +// +// @param __relative_priority +// On output, a relative priority offset within the QOS class. +// This value may be NULL in which case no value is returned. +// +// @return +// Zero if successful, otherwise an errno value. +// +// llgo:link Thread.GetQosClassNp C.pthread_get_qos_class_np +func (self Thread) GetQosClassNp(__qos_class *c.Uint, __relative_priority *c.Int) c.Int { + return 0 +} + +// ! +// @function pthread_override_qos_class_start_np +// +// @abstract +// Starts a QOS class override of the specified target thread. +// +// @discussion +// Starting a QOS class override of the specified target thread expresses that +// an item of pending work classified with the specified QOS class and relative +// priority depends on the completion of the work currently being executed by +// the thread (e.g. due to ordering requirements). +// +// While overrides are in effect, the specified target thread will execute at +// the maximum QOS class and relative priority of all overrides and of the QOS +// class requested by the thread itself. +// +// Starting a QOS class override does not modify the target thread's requested +// QOS class value and the effect of an override is not visible to the +// qos_class_self() and pthread_get_qos_class_np() interfaces. +// +// The returned newly allocated override object is intended to be associated +// with the item of pending work in question. Once the dependency has been +// satisfied and enabled that work to begin executing, the QOS class override +// must be ended by passing the associated override object to +// pthread_override_qos_class_end_np(). Failure to do so will result in the +// associated resources to be leaked and the target thread to be permanently +// executed at an inappropriately elevated QOS class. +// +// @param __pthread +// The target thread to modify. +// +// @param __qos_class +// A QOS class value: +// - QOS_CLASS_USER_INTERACTIVE +// - QOS_CLASS_USER_INITIATED +// - QOS_CLASS_DEFAULT +// - QOS_CLASS_UTILITY +// - QOS_CLASS_BACKGROUND +// +// NULL will be returned if any other value is provided. +// +// @param __relative_priority +// A relative priority within the QOS class. This value is a negative offset +// from the maximum supported scheduler priority for the given class. +// NULL will be returned if the value is greater than zero or less than +// QOS_MIN_RELATIVE_PRIORITY. +// +// @return +// A newly allocated override object if successful, or NULL if the override +// could not be started. +// +// llgo:link Thread.OverrideQosClassStartNp C.pthread_override_qos_class_start_np +func (self Thread) OverrideQosClassStartNp(__qos_class c.Uint, __relative_priority c.Int) OverrideT { + return nil +} + +// ! +// @function pthread_override_qos_class_end_np +// +// @abstract +// Ends a QOS class override. +// +// @discussion +// Passing an override object returned by pthread_override_qos_class_start_np() +// ends the QOS class override started by that call and deallocates all +// associated resources as well as the override object itself. +// +// The thread starting and the thread ending a QOS class override need not be +// identical. If the thread ending the override is the the target thread of the +// override itself, it should take care to elevate its requested QOS class +// appropriately with pthread_set_qos_class_self_np() before ending the +// override. +// +// @param __override +// An override object returned by pthread_override_qos_class_start_np(). +// +// @return +// Zero if successful, otherwise an errno value. +// +// llgo:link OverrideT.OverrideQosClassEndNp C.pthread_override_qos_class_end_np +func (self OverrideT) OverrideQosClassEndNp() c.Int { + return 0 +} + +const ( + PTHREAD_CREATE_JOINABLE = 1 + PTHREAD_CREATE_DETACHED = 2 +) + +const ( + PTHREAD_INHERIT_SCHED = 1 + PTHREAD_EXPLICIT_SCHED = 2 +) + +const ( + // Cancel takes place at next cancellation point + PTHREAD_CANCEL_ENABLE = 1 + // Cancel postponed + PTHREAD_CANCEL_DISABLE = 0 + // Cancel waits until cancellation point + PTHREAD_CANCEL_DEFERRED = 2 + // Cancel occurs immediately + PTHREAD_CANCEL_ASYNCHRONOUS = 0 +) + +// We only support PTHREAD_SCOPE_SYSTEM +const ( + PTHREAD_SCOPE_SYSTEM = 1 + PTHREAD_SCOPE_PROCESS = 2 +) + +const ( + PTHREAD_PROCESS_SHARED = 1 + PTHREAD_PROCESS_PRIVATE = 2 +) + +// Mutex protocol attributes +const ( + PTHREAD_PRIO_NONE = 0 + PTHREAD_PRIO_INHERIT = 1 + PTHREAD_PRIO_PROTECT = 2 +) + +// Mutex type attributes +const ( + PTHREAD_MUTEX_NORMAL = 0 + PTHREAD_MUTEX_ERRORCHECK = 1 + PTHREAD_MUTEX_RECURSIVE = 2 + PTHREAD_MUTEX_DEFAULT = 0 +) + +// Mutex policy attributes +const ( + PTHREAD_MUTEX_POLICY_FAIRSHARE_NP = 1 + PTHREAD_MUTEX_POLICY_FIRSTFIT_NP = 3 +) + +// Prototypes for all PTHREAD interfaces +// +// llgo:type C +type llcppgCallback28 = func() + +// llgo:type C +type llcppgCallback29 = func() + +// llgo:type C +type llcppgCallback30 = func() + +// llgo:type C +type llcppgCallback27 = func(_llcppg_param1 unsafe.Pointer) unsafe.Pointer + +// llgo:type C +type llcppgCallback26 = func(_llcppg_param1 unsafe.Pointer) + +// Like pthread_create(), but leaves the thread suspended +// +// llgo:type C +type llcppgCallback24 = func(_llcppg_param1 unsafe.Pointer) unsafe.Pointer + +// ! +// @typedef pthread_jit_write_callback_t +// The type of a function that can be supplied to {@link +// pthread_jit_write_with_callback_np} to write to the MAP_JIT region while it +// is writeable. +// +// @param ctx +// A pointer to context that will be passed through to the callback function. +// +// @result +// A result code to be returned to the caller of @{link +// pthread_jit_write_with_callback_np}. The system does not interpret/act on +// the value of this result. +// +// llgo:type C +type JitWriteCallbackT = func(_llcppg_param1 unsafe.Pointer) c.Int + +//go:linkname Atfork C.pthread_atfork +func Atfork(_llcppg_param1 llcppgCallback30, _llcppg_param2 llcppgCallback29, _llcppg_param3 llcppgCallback28) c.Int + +// llgo:link (*Attr).Destroy C.pthread_attr_destroy +func (self *Attr) Destroy() c.Int { return 0 } + +// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate +func (self *Attr) GetDetached(_llcppg_param2 *c.Int) c.Int { return 0 } + +// llgo:link (*Attr).Getguardsize C.pthread_attr_getguardsize +func (self *Attr) Getguardsize(_llcppg_param2 *c.SizeT) c.Int { + return 0 +} + +// llgo:link (*Attr).Getinheritsched C.pthread_attr_getinheritsched +func (self *Attr) Getinheritsched(_llcppg_param2 *c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Getschedparam C.pthread_attr_getschedparam +func (self *Attr) Getschedparam(_llcppg_param2 *llos.SchedParam) c.Int { + return 0 +} + +// llgo:link (*Attr).Getschedpolicy C.pthread_attr_getschedpolicy +func (self *Attr) Getschedpolicy(_llcppg_param2 *c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Getscope C.pthread_attr_getscope +func (self *Attr) Getscope(_llcppg_param2 *c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Getstack C.pthread_attr_getstack +func (self *Attr) Getstack(_llcppg_param2 *unsafe.Pointer, _llcppg_param3 *c.SizeT) c.Int { + return 0 +} + +// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr +func (self *Attr) GetStackAddr(_llcppg_param2 *unsafe.Pointer) c.Int { return 0 } + +// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize +func (self *Attr) GetStackSize(_llcppg_param2 *c.SizeT) c.Int { return 0 } + +// llgo:link (*Attr).Init C.pthread_attr_init +func (self *Attr) Init() c.Int { return 0 } + +// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate +func (self *Attr) SetDetached(_llcppg_param2 c.Int) c.Int { return 0 } + +// llgo:link (*Attr).Setguardsize C.pthread_attr_setguardsize +func (self *Attr) Setguardsize(_llcppg_param2 c.SizeT) c.Int { + return 0 +} + +// llgo:link (*Attr).Setinheritsched C.pthread_attr_setinheritsched +func (self *Attr) Setinheritsched(_llcppg_param2 c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Setschedparam C.pthread_attr_setschedparam +func (self *Attr) Setschedparam(_llcppg_param2 *llos.SchedParam) c.Int { + return 0 +} + +// llgo:link (*Attr).Setschedpolicy C.pthread_attr_setschedpolicy +func (self *Attr) Setschedpolicy(_llcppg_param2 c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Setscope C.pthread_attr_setscope +func (self *Attr) Setscope(_llcppg_param2 c.Int) c.Int { + return 0 +} + +// llgo:link (*Attr).Setstack C.pthread_attr_setstack +func (self *Attr) Setstack(_llcppg_param2 unsafe.Pointer, _llcppg_param3 c.SizeT) c.Int { + return 0 +} + +// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr +func (self *Attr) SetStackAddr(_llcppg_param2 unsafe.Pointer) c.Int { return 0 } + +// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize +func (self *Attr) SetStackSize(_llcppg_param2 c.SizeT) c.Int { return 0 } + +//go:linkname Cancel C.pthread_cancel +func Cancel(self Thread) c.Int + +//go:linkname NativeCreate C.pthread_create +func NativeCreate(_llcppg_param1 *Thread, _llcppg_param2 *Attr, _llcppg_param3 llcppgCallback27, _llcppg_param4 unsafe.Pointer) c.Int + +// llgo:link Thread.Detach C.pthread_detach +func (self Thread) Detach() c.Int { + return 0 +} + +//go:linkname Equal C.pthread_equal +func Equal(_llcppg_param1 Thread, _llcppg_param2 Thread) c.Int + +//go:linkname Exit C.pthread_exit +func Exit(_llcppg_param1 unsafe.Pointer) + +//go:linkname Getconcurrency C.pthread_getconcurrency +func Getconcurrency() c.Int + +// llgo:link Thread.Getschedparam C.pthread_getschedparam +func (self Thread) Getschedparam(_llcppg_param2 *c.Int, _llcppg_param3 *llos.SchedParam) c.Int { + return 0 +} + +// llgo:link Key.Get C.pthread_getspecific +func (self Key) Get() unsafe.Pointer { return nil } + +// llgo:link Thread.NativeJoin C.pthread_join +func (self Thread) NativeJoin(_llcppg_param2 *unsafe.Pointer) c.Int { + return 0 +} + +// llgo:link (*Key).Create C.pthread_key_create +func (self *Key) Create(_llcppg_param2 llcppgCallback26) c.Int { return 0 } + +// llgo:link Key.Delete C.pthread_key_delete +func (self Key) Delete() c.Int { return 0 } + +//go:linkname Self C.pthread_self +func Self() Thread + +//go:linkname Setcancelstate C.pthread_setcancelstate +func Setcancelstate(_llcppg_param1 c.Int, _llcppg_param2 *c.Int) c.Int + +//go:linkname Setcanceltype C.pthread_setcanceltype +func Setcanceltype(_llcppg_param1 c.Int, _llcppg_param2 *c.Int) c.Int + +//go:linkname Setconcurrency C.pthread_setconcurrency +func Setconcurrency(_llcppg_param1 c.Int) c.Int + +// llgo:link Thread.Setschedparam C.pthread_setschedparam +func (self Thread) Setschedparam(_llcppg_param2 c.Int, _llcppg_param3 *llos.SchedParam) c.Int { + return 0 +} + +// llgo:link Key.Set C.pthread_setspecific +func (self Key) Set(_llcppg_param2 unsafe.Pointer) c.Int { return 0 } + +//go:linkname Testcancel C.pthread_testcancel +func Testcancel() + +// returns non-zero if pthread_create or cthread_fork have been called +// +//go:linkname IsThreadedNp C.pthread_is_threaded_np +func IsThreadedNp() c.Int + +// llgo:link Thread.ThreadidNp C.pthread_threadid_np +func (self Thread) ThreadidNp(_llcppg_param2 *c.UlongLong) c.Int { + return 0 +} + +// SPI to set and get pthread name +// +// llgo:link Thread.GetnameNp C.pthread_getname_np +func (self Thread) GetnameNp(_llcppg_param2 *c.Char, _llcppg_param3 c.SizeT) c.Int { + return 0 +} + +//go:linkname SetnameNp C.pthread_setname_np +func SetnameNp(_llcppg_param1 *c.Char) c.Int + +// returns non-zero if the current thread is the main thread +// +//go:linkname MainNp C.pthread_main_np +func MainNp() c.Int + +// return the mach thread bound to the pthread +// +// llgo:link Thread.MachThreadNp C.pthread_mach_thread_np +func (self Thread) MachThreadNp() llos.MachPortT { + return 0 +} + +// llgo:link Thread.GetStacksizeNp C.pthread_get_stacksize_np +func (self Thread) GetStacksizeNp() c.SizeT { + return 0 +} + +// llgo:link Thread.GetStackaddrNp C.pthread_get_stackaddr_np +func (self Thread) GetStackaddrNp() unsafe.Pointer { + return nil +} + +//go:linkname CreateSuspendedNp C.pthread_create_suspended_np +func CreateSuspendedNp(_llcppg_param1 *Thread, _llcppg_param2 *Attr, _llcppg_param3 llcppgCallback24, _llcppg_param4 unsafe.Pointer) c.Int + +// llgo:link Thread.Kill C.pthread_kill +func (self Thread) Kill(_llcppg_param2 c.Int) c.Int { + return 0 +} + +//go:linkname FromMachThreadNp C.pthread_from_mach_thread_np +func FromMachThreadNp(_llcppg_param1 llos.MachPortT) Thread + +//go:linkname Sigmask C.pthread_sigmask +func Sigmask(_llcppg_param1 c.Int, _llcppg_param2 *c.Uint, _llcppg_param3 *c.Uint) c.Int + +//go:linkname YieldNp C.pthread_yield_np +func YieldNp() + +//go:linkname JitWriteProtectNp C.pthread_jit_write_protect_np +func JitWriteProtectNp(enabled c.Int) + +//go:linkname JitWriteProtectSupportedNp C.pthread_jit_write_protect_supported_np +func JitWriteProtectSupportedNp() c.Int + +// ! +// @function pthread_jit_write_with_callback_np +// +// @abstract +// Toggles per-thread write-protection of the MAP_JIT region to writeable, +// invokes an allowed callback function to write to it, and toggles protection +// back to executable. +// +// @param callback +// The callback function to invoke to write to the MAP_JIT region. It must be +// statically allowed using {@link PTHREAD_JIT_WRITE_ALLOW_CALLBACKS_NP}. +// +// @param ctx +// Context to pass through to the invocation of the callback function. +// +// @result +// The result code returned by the callback function. +// +// @discussion +// This function assumes that the MAP_JIT region has executable protection when +// called. It is therefore invalid to call it recursively from within a write +// callback. The implementation does not detect such invalid recursive calls, +// so the client is responsible for preventing them. +// +// Callbacks _must not_ perform any non-local transfer of control flow (e.g. +// throw an exception, longjmp(3)), as doing so would leave the MAP_JIT region +// writeable. +// +// On systems where pthread_jit_write_protect_supported_np(3) is false, this +// function calls @callback directly and does nothing else. +// +// This function only enforces that @callback is allowed if the caller has the +// com.apple.security.cs.jit-write-allowlist entitlement. That entitlement also +// disallows use of pthread_jit_write_protect_np(3). Adopting the entitlement +// is therefore crucial in realizing the security benefits of this interface. +// +// If the entitlement is not present then this function toggles protection of +// the MAP_JIT to writeable, calls @callback and then toggles protection back to +// executable, without validating that @callback is an allowed function. This +// behavior is intended to permit independent adoption of this interface by +// libraries - once all libraries in an application have adopted, the +// application should add the entitlement. +// +// By default, only callbacks in libraries/images present at process start-up +// are allowed - callbacks in images loaded dynamically via dlopen(3)/etc. are +// not permitted. However, if the additional entitlement +// com.apple.security.cs.jit-write-allowlist-freeze-late is _also_ present, any +// callbacks in dlopen'd libraries are also added to the set of allowed +// callbacks until the {@link pthread_jit_write_freeze_callbacks_np} function is +// called. +// +// The goal of this interface is to allow applications that execute JIT-compiled +// code to mitigate against attempts from attackers to escalate to code +// execution by getting their own instructions written to the MAP_JIT region. +// +// Callbacks should assume an attacker can control the input to this function. +// They must therefore carefully validate the data that they are passed and do +// so using as little attackable state as possible. This means simplifying +// control flow and avoiding spills of sensitive registers (e.g. those used for +// validation or control flow). +// +// In the event a callback detects that its input is invalid, it should either +// abort in the simplest fashion possible (preferring e.g. __builtin_trap() over +// abort(3), the latter being encumbered by various conformance requirements) or +// return a result indicating failure. +// +//go:linkname JitWriteWithCallbackNp C.pthread_jit_write_with_callback_np +func JitWriteWithCallbackNp(callback JitWriteCallbackT, ctx unsafe.Pointer) c.Int + +// ! +// @function pthread_jit_write_freeze_callbacks_np +// +// @abstract +// Freezes the set of allowed pthread JIT write callbacks, preventing any +// callbacks in subsequently dlopen'd libraries from being allowed as arguments +// to {@link pthread_jit_write_with_callback_np} +// +// @discussion +// If the com.apple.security.cs.jit-write-allowlist-freeze-late entitlement is +// present, this function must be called exactly once after all libraries +// containing JIT write callbacks have been loaded to prevent any further +// runtime modifications to the set of allowed callbacks. Failing to call this +// function before calling pthread_jit_write_with_callback_np(3) for the first +// time is an error, as is calling it multiple times. +// +// If the jit-write-allowlist-freeze-late entitlement is not present, calling +// this function is an error. +// +// If an application does not need to dlopen(3) any libraries or frameworks +// containing needed JIT write callbacks, it is best to avoid the +// jit-write-allowlist-freeze-late entitlement and accompanying need to call +// this function, as this allows the runtime to automatically freeze the set of +// allowed callbacks early in process initialization. +// +//go:linkname JitWriteFreezeCallbacksNp C.pthread_jit_write_freeze_callbacks_np +func JitWriteFreezeCallbacksNp() + +// ! +// @function pthread_cpu_number_np +// +// @param cpu_number_out +// The CPU number that the thread was running on at the time of query. +// This cpu number is in the interval [0, ncpus) (from sysctlbyname("hw.ncpu")) +// +// @result +// This function returns 0 or the value of errno if an error occurred. +// +// @note +// Optimizations of per-CPU datastructures based on the result of this function +// still require synchronization since it is not guaranteed that the thread will +// still be on the same CPU by the time the function returns. +// +//go:linkname CpuNumberNp C.pthread_cpu_number_np +func CpuNumberNp(cpu_number_out *c.SizeT) c.Int + +//go:linkname SetugidNp C.pthread_setugid_np +func SetugidNp(_llcppg_param1 c.Uint, _llcppg_param2 c.Uint) c.Int + +//go:linkname GetugidNp C.pthread_getugid_np +func GetugidNp(_llcppg_param1 *c.Uint, _llcppg_param2 *c.Uint) c.Int + +type Attr struct { + X__Sig c.Long + X__Opaque [56]c.Char +} + +type AttrT = Attr + +type Key c.Ulong diff --git a/c/pthread/libc_linux_amd64.go b/c/pthread/libc_linux_amd64.go new file mode 100644 index 00000000..ba6880c9 --- /dev/null +++ b/c/pthread/libc_linux_amd64.go @@ -0,0 +1,373 @@ +//go:build linux && amd64 && !android + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package pthread + +import ( + "github.com/goplus/lib/c" + llos "github.com/goplus/lib/c/os" + llsignal "github.com/goplus/lib/c/signal" + "unsafe" +) + +// Modify the signal mask for the calling thread. The arguments have +// the same meaning as for sigprocmask(2). +// +//go:linkname Sigmask C.pthread_sigmask +func Sigmask(__how c.Int, __newmask *llsignal.SigsetT, __oldmask *llsignal.SigsetT) c.Int + +// Send signal SIGNO to the given thread. +// +//go:linkname Kill C.pthread_kill +func Kill(__threadid Thread, __signo c.Int) c.Int + +// Single execution handling. +const PTHREAD_ONCE_INIT = 0 + +// Value returned by 'pthread_barrier_wait' for one of the threads after +// the required number of threads have called this function. +// -1 is distinct from 0 and all errno constants +const PTHREAD_BARRIER_SERIAL_THREAD = -1 + +// Detach state. +const ( + PTHREAD_CREATE_JOINABLE = 0 + PTHREAD_CREATE_DETACHED = 1 +) + +// Mutex types. +const ( + PTHREAD_MUTEX_TIMED_NP = 0 + PTHREAD_MUTEX_RECURSIVE_NP = 1 + PTHREAD_MUTEX_ERRORCHECK_NP = 2 + PTHREAD_MUTEX_ADAPTIVE_NP = 3 + PTHREAD_MUTEX_NORMAL = 0 + PTHREAD_MUTEX_RECURSIVE = 1 + PTHREAD_MUTEX_ERRORCHECK = 2 + PTHREAD_MUTEX_DEFAULT = 0 +) + +// Robust mutex or not flags. +const ( + PTHREAD_MUTEX_STALLED = 0 + PTHREAD_MUTEX_STALLED_NP = 0 + PTHREAD_MUTEX_ROBUST = 1 + PTHREAD_MUTEX_ROBUST_NP = 1 +) + +// Mutex protocols. +const ( + PTHREAD_PRIO_NONE = 0 + PTHREAD_PRIO_INHERIT = 1 + PTHREAD_PRIO_PROTECT = 2 +) + +const ( + PTHREAD_RWLOCK_PREFER_READER_NP = 0 + PTHREAD_RWLOCK_PREFER_WRITER_NP = 1 + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 2 + PTHREAD_RWLOCK_DEFAULT_NP = 0 +) + +// Scheduler inheritance. +const ( + PTHREAD_INHERIT_SCHED = 0 + PTHREAD_EXPLICIT_SCHED = 1 +) + +// Scope handling. +const ( + PTHREAD_SCOPE_SYSTEM = 0 + PTHREAD_SCOPE_PROCESS = 1 +) + +// Process shared or private flag. +const ( + PTHREAD_PROCESS_PRIVATE = 0 + PTHREAD_PROCESS_SHARED = 1 +) + +// Cancellation +const ( + PTHREAD_CANCEL_ENABLE = 0 + PTHREAD_CANCEL_DISABLE = 1 +) + +const ( + PTHREAD_CANCEL_DEFERRED = 0 + PTHREAD_CANCEL_ASYNCHRONOUS = 1 +) + +// Create a new thread, starting with execution of START-ROUTINE +// getting passed ARG. Creation attributed come from ATTR. The new +// handle is stored in *NEWTHREAD. +// +// llgo:type C +type llcppgCallback12 = func(_llcppg_param1 unsafe.Pointer) unsafe.Pointer + +// Create a key value identifying a location in the thread-specific +// data area. Each thread maintains a distinct thread-specific data +// area. DESTR_FUNCTION, if non-NULL, is called with the value +// associated to that key when the key is destroyed. +// DESTR_FUNCTION is not called if the value associated is NULL when +// the key is destroyed. +// +// llgo:type C +type llcppgCallback9 = func(_llcppg_param1 unsafe.Pointer) + +// llgo:type C +type llcppgCallback6 = func() + +// llgo:type C +type llcppgCallback7 = func() + +// llgo:type C +type llcppgCallback8 = func() + +//go:linkname NativeCreate C.pthread_create +func NativeCreate(__newthread *Thread, __attr *Attr, __start_routine llcppgCallback12, __arg unsafe.Pointer) c.Int + +// Terminate calling thread. +// +// The registered cleanup handlers are called via exception handling +// so we cannot mark this function with __THROW. +// +//go:linkname Exit C.pthread_exit +func Exit(__retval unsafe.Pointer) + +// Make calling thread wait for termination of the thread TH. The +// exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN +// is not NULL. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +//go:linkname NativeJoin C.pthread_join +func NativeJoin(__th Thread, __thread_return *unsafe.Pointer) c.Int + +// Indicate that the thread TH is never to be joined with PTHREAD_JOIN. +// The resources of TH will therefore be freed immediately when it +// terminates, instead of waiting for another thread to perform PTHREAD_JOIN +// on it. +// +//go:linkname Detach C.pthread_detach +func Detach(__th Thread) c.Int + +// Obtain the identifier of the current thread. +// +//go:linkname Self C.pthread_self +func Self() Thread + +// Compare two thread identifiers. +// +//go:linkname Equal C.pthread_equal +func Equal(__thread1 Thread, __thread2 Thread) c.Int + +// Initialize thread attribute *ATTR with default attributes +// (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER, +// no user-provided stack). +// +// llgo:link (*Attr).Init C.pthread_attr_init +func (self *Attr) Init() c.Int { return 0 } + +// Destroy thread attribute *ATTR. +// +// llgo:link (*Attr).Destroy C.pthread_attr_destroy +func (self *Attr) Destroy() c.Int { return 0 } + +// Get detach state attribute. +// +// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate +func (self *Attr) GetDetached(__detachstate *c.Int) c.Int { return 0 } + +// Set detach state attribute. +// +// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate +func (self *Attr) SetDetached(__detachstate c.Int) c.Int { return 0 } + +// Get the size of the guard area created for stack overflow protection. +// +// llgo:link (*Attr).Getguardsize C.pthread_attr_getguardsize +func (self *Attr) Getguardsize(__guardsize *c.SizeT) c.Int { + return 0 +} + +// Set the size of the guard area created for stack overflow protection. +// +// llgo:link (*Attr).Setguardsize C.pthread_attr_setguardsize +func (self *Attr) Setguardsize(__guardsize c.SizeT) c.Int { + return 0 +} + +// Return in *PARAM the scheduling parameters of *ATTR. +// +// llgo:link (*Attr).Getschedparam C.pthread_attr_getschedparam +func (self *Attr) Getschedparam(__param *llos.SchedParam) c.Int { + return 0 +} + +// Set scheduling parameters (priority, etc) in *ATTR according to PARAM. +// +// llgo:link (*Attr).Setschedparam C.pthread_attr_setschedparam +func (self *Attr) Setschedparam(__param *llos.SchedParam) c.Int { + return 0 +} + +// Return in *POLICY the scheduling policy of *ATTR. +// +// llgo:link (*Attr).Getschedpolicy C.pthread_attr_getschedpolicy +func (self *Attr) Getschedpolicy(__policy *c.Int) c.Int { + return 0 +} + +// Set scheduling policy in *ATTR according to POLICY. +// +// llgo:link (*Attr).Setschedpolicy C.pthread_attr_setschedpolicy +func (self *Attr) Setschedpolicy(__policy c.Int) c.Int { + return 0 +} + +// Return in *INHERIT the scheduling inheritance mode of *ATTR. +// +// llgo:link (*Attr).Getinheritsched C.pthread_attr_getinheritsched +func (self *Attr) Getinheritsched(__inherit *c.Int) c.Int { + return 0 +} + +// Set scheduling inheritance mode in *ATTR according to INHERIT. +// +// llgo:link (*Attr).Setinheritsched C.pthread_attr_setinheritsched +func (self *Attr) Setinheritsched(__inherit c.Int) c.Int { + return 0 +} + +// Return in *SCOPE the scheduling contention scope of *ATTR. +// +// llgo:link (*Attr).Getscope C.pthread_attr_getscope +func (self *Attr) Getscope(__scope *c.Int) c.Int { + return 0 +} + +// Set scheduling contention scope in *ATTR according to SCOPE. +// +// llgo:link (*Attr).Setscope C.pthread_attr_setscope +func (self *Attr) Setscope(__scope c.Int) c.Int { + return 0 +} + +// Return the previously set address for the stack. +// +// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr +func (self *Attr) GetStackAddr(__stackaddr *unsafe.Pointer) c.Int { return 0 } + +// Set the starting address of the stack of the thread to be created. +// Depending on whether the stack grows up or down the value must either +// be higher or lower than all the address in the memory block. The +// minimal size of the block must be PTHREAD_STACK_MIN. +// +// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr +func (self *Attr) SetStackAddr(__stackaddr unsafe.Pointer) c.Int { return 0 } + +// Return the currently used minimal stack size. +// +// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize +func (self *Attr) GetStackSize(__stacksize *c.SizeT) c.Int { return 0 } + +// Add information about the minimum stack size needed for the thread +// to be started. This size must never be less than PTHREAD_STACK_MIN +// and must also not exceed the system limits. +// +// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize +func (self *Attr) SetStackSize(__stacksize c.SizeT) c.Int { return 0 } + +// Return the previously set address for the stack. +// +// llgo:link (*Attr).Getstack C.pthread_attr_getstack +func (self *Attr) Getstack(__stackaddr *unsafe.Pointer, __stacksize *c.SizeT) c.Int { + return 0 +} + +// The following two interfaces are intended to replace the last two. They +// require setting the address as well as the size since only setting the +// address will make the implementation on some architectures impossible. +// +// llgo:link (*Attr).Setstack C.pthread_attr_setstack +func (self *Attr) Setstack(__stackaddr unsafe.Pointer, __stacksize c.SizeT) c.Int { + return 0 +} + +// Set the scheduling parameters for TARGET_THREAD according to POLICY +// and *PARAM. +// +//go:linkname Setschedparam C.pthread_setschedparam +func Setschedparam(__target_thread Thread, __policy c.Int, __param *llos.SchedParam) c.Int + +// Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. +// +//go:linkname Getschedparam C.pthread_getschedparam +func Getschedparam(__target_thread Thread, __policy *c.Int, __param *llos.SchedParam) c.Int + +// Set the scheduling priority for TARGET_THREAD. +// +//go:linkname Setschedprio C.pthread_setschedprio +func Setschedprio(__target_thread Thread, __prio c.Int) c.Int + +// Set cancelability state of current thread to STATE, returning old +// state in *OLDSTATE if OLDSTATE is not NULL. +// +//go:linkname Setcancelstate C.pthread_setcancelstate +func Setcancelstate(__state c.Int, __oldstate *c.Int) c.Int + +// Set cancellation state of current thread to TYPE, returning the old +// type in *OLDTYPE if OLDTYPE is not NULL. +// +//go:linkname Setcanceltype C.pthread_setcanceltype +func Setcanceltype(__type c.Int, __oldtype *c.Int) c.Int + +// Cancel THREAD immediately or at the next possibility. +// +//go:linkname Cancel C.pthread_cancel +func Cancel(__th Thread) c.Int + +// Test for pending cancellation for the current thread and terminate +// the thread as per pthread_exit(PTHREAD_CANCELED) if it has been +// cancelled. +// +//go:linkname Testcancel C.pthread_testcancel +func Testcancel() + +// llgo:link (*Key).Create C.pthread_key_create +func (self *Key) Create(__destr_function llcppgCallback9) c.Int { return 0 } + +// Destroy KEY. +// +// llgo:link Key.Delete C.pthread_key_delete +func (self Key) Delete() c.Int { return 0 } + +// Return current value of the thread-specific data slot identified by KEY. +// +// llgo:link Key.Get C.pthread_getspecific +func (self Key) Get() unsafe.Pointer { return nil } + +// Store POINTER in the thread-specific data slot identified by KEY. +// +// llgo:link Key.Set C.pthread_setspecific +func (self Key) Set(__pointer unsafe.Pointer) c.Int { return 0 } + +// Get ID of CPU-time clock for thread THREAD_ID. +// +//go:linkname Getcpuclockid C.pthread_getcpuclockid +func Getcpuclockid(__thread_id Thread, __clock_id *c.Int) c.Int + +//go:linkname Atfork C.pthread_atfork +func Atfork(__prepare llcppgCallback8, __parent llcppgCallback7, __child llcppgCallback6) c.Int + +type Attr struct { + _xgo_union [7]uint64 +} + +type AttrT = Attr + +type Key c.Uint diff --git a/c/pthread/libc_linux_arm64.go b/c/pthread/libc_linux_arm64.go new file mode 100644 index 00000000..d71bfccf --- /dev/null +++ b/c/pthread/libc_linux_arm64.go @@ -0,0 +1,373 @@ +//go:build linux && arm64 && !android + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package pthread + +import ( + "github.com/goplus/lib/c" + llos "github.com/goplus/lib/c/os" + llsignal "github.com/goplus/lib/c/signal" + "unsafe" +) + +// Modify the signal mask for the calling thread. The arguments have +// the same meaning as for sigprocmask(2). +// +//go:linkname Sigmask C.pthread_sigmask +func Sigmask(__how c.Int, __newmask *llsignal.SigsetT, __oldmask *llsignal.SigsetT) c.Int + +// Send signal SIGNO to the given thread. +// +//go:linkname Kill C.pthread_kill +func Kill(__threadid Thread, __signo c.Int) c.Int + +// Single execution handling. +const PTHREAD_ONCE_INIT = 0 + +// Value returned by 'pthread_barrier_wait' for one of the threads after +// the required number of threads have called this function. +// -1 is distinct from 0 and all errno constants +const PTHREAD_BARRIER_SERIAL_THREAD = -1 + +// Detach state. +const ( + PTHREAD_CREATE_JOINABLE = 0 + PTHREAD_CREATE_DETACHED = 1 +) + +// Mutex types. +const ( + PTHREAD_MUTEX_TIMED_NP = 0 + PTHREAD_MUTEX_RECURSIVE_NP = 1 + PTHREAD_MUTEX_ERRORCHECK_NP = 2 + PTHREAD_MUTEX_ADAPTIVE_NP = 3 + PTHREAD_MUTEX_NORMAL = 0 + PTHREAD_MUTEX_RECURSIVE = 1 + PTHREAD_MUTEX_ERRORCHECK = 2 + PTHREAD_MUTEX_DEFAULT = 0 +) + +// Robust mutex or not flags. +const ( + PTHREAD_MUTEX_STALLED = 0 + PTHREAD_MUTEX_STALLED_NP = 0 + PTHREAD_MUTEX_ROBUST = 1 + PTHREAD_MUTEX_ROBUST_NP = 1 +) + +// Mutex protocols. +const ( + PTHREAD_PRIO_NONE = 0 + PTHREAD_PRIO_INHERIT = 1 + PTHREAD_PRIO_PROTECT = 2 +) + +const ( + PTHREAD_RWLOCK_PREFER_READER_NP = 0 + PTHREAD_RWLOCK_PREFER_WRITER_NP = 1 + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 2 + PTHREAD_RWLOCK_DEFAULT_NP = 0 +) + +// Scheduler inheritance. +const ( + PTHREAD_INHERIT_SCHED = 0 + PTHREAD_EXPLICIT_SCHED = 1 +) + +// Scope handling. +const ( + PTHREAD_SCOPE_SYSTEM = 0 + PTHREAD_SCOPE_PROCESS = 1 +) + +// Process shared or private flag. +const ( + PTHREAD_PROCESS_PRIVATE = 0 + PTHREAD_PROCESS_SHARED = 1 +) + +// Cancellation +const ( + PTHREAD_CANCEL_ENABLE = 0 + PTHREAD_CANCEL_DISABLE = 1 +) + +const ( + PTHREAD_CANCEL_DEFERRED = 0 + PTHREAD_CANCEL_ASYNCHRONOUS = 1 +) + +// Create a new thread, starting with execution of START-ROUTINE +// getting passed ARG. Creation attributed come from ATTR. The new +// handle is stored in *NEWTHREAD. +// +// llgo:type C +type llcppgCallback12 = func(_llcppg_param1 unsafe.Pointer) unsafe.Pointer + +// Create a key value identifying a location in the thread-specific +// data area. Each thread maintains a distinct thread-specific data +// area. DESTR_FUNCTION, if non-NULL, is called with the value +// associated to that key when the key is destroyed. +// DESTR_FUNCTION is not called if the value associated is NULL when +// the key is destroyed. +// +// llgo:type C +type llcppgCallback9 = func(_llcppg_param1 unsafe.Pointer) + +// llgo:type C +type llcppgCallback6 = func() + +// llgo:type C +type llcppgCallback7 = func() + +// llgo:type C +type llcppgCallback8 = func() + +//go:linkname NativeCreate C.pthread_create +func NativeCreate(__newthread *Thread, __attr *Attr, __start_routine llcppgCallback12, __arg unsafe.Pointer) c.Int + +// Terminate calling thread. +// +// The registered cleanup handlers are called via exception handling +// so we cannot mark this function with __THROW. +// +//go:linkname Exit C.pthread_exit +func Exit(__retval unsafe.Pointer) + +// Make calling thread wait for termination of the thread TH. The +// exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN +// is not NULL. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +//go:linkname NativeJoin C.pthread_join +func NativeJoin(__th Thread, __thread_return *unsafe.Pointer) c.Int + +// Indicate that the thread TH is never to be joined with PTHREAD_JOIN. +// The resources of TH will therefore be freed immediately when it +// terminates, instead of waiting for another thread to perform PTHREAD_JOIN +// on it. +// +//go:linkname Detach C.pthread_detach +func Detach(__th Thread) c.Int + +// Obtain the identifier of the current thread. +// +//go:linkname Self C.pthread_self +func Self() Thread + +// Compare two thread identifiers. +// +//go:linkname Equal C.pthread_equal +func Equal(__thread1 Thread, __thread2 Thread) c.Int + +// Initialize thread attribute *ATTR with default attributes +// (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER, +// no user-provided stack). +// +// llgo:link (*Attr).Init C.pthread_attr_init +func (self *Attr) Init() c.Int { return 0 } + +// Destroy thread attribute *ATTR. +// +// llgo:link (*Attr).Destroy C.pthread_attr_destroy +func (self *Attr) Destroy() c.Int { return 0 } + +// Get detach state attribute. +// +// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate +func (self *Attr) GetDetached(__detachstate *c.Int) c.Int { return 0 } + +// Set detach state attribute. +// +// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate +func (self *Attr) SetDetached(__detachstate c.Int) c.Int { return 0 } + +// Get the size of the guard area created for stack overflow protection. +// +// llgo:link (*Attr).Getguardsize C.pthread_attr_getguardsize +func (self *Attr) Getguardsize(__guardsize *c.SizeT) c.Int { + return 0 +} + +// Set the size of the guard area created for stack overflow protection. +// +// llgo:link (*Attr).Setguardsize C.pthread_attr_setguardsize +func (self *Attr) Setguardsize(__guardsize c.SizeT) c.Int { + return 0 +} + +// Return in *PARAM the scheduling parameters of *ATTR. +// +// llgo:link (*Attr).Getschedparam C.pthread_attr_getschedparam +func (self *Attr) Getschedparam(__param *llos.SchedParam) c.Int { + return 0 +} + +// Set scheduling parameters (priority, etc) in *ATTR according to PARAM. +// +// llgo:link (*Attr).Setschedparam C.pthread_attr_setschedparam +func (self *Attr) Setschedparam(__param *llos.SchedParam) c.Int { + return 0 +} + +// Return in *POLICY the scheduling policy of *ATTR. +// +// llgo:link (*Attr).Getschedpolicy C.pthread_attr_getschedpolicy +func (self *Attr) Getschedpolicy(__policy *c.Int) c.Int { + return 0 +} + +// Set scheduling policy in *ATTR according to POLICY. +// +// llgo:link (*Attr).Setschedpolicy C.pthread_attr_setschedpolicy +func (self *Attr) Setschedpolicy(__policy c.Int) c.Int { + return 0 +} + +// Return in *INHERIT the scheduling inheritance mode of *ATTR. +// +// llgo:link (*Attr).Getinheritsched C.pthread_attr_getinheritsched +func (self *Attr) Getinheritsched(__inherit *c.Int) c.Int { + return 0 +} + +// Set scheduling inheritance mode in *ATTR according to INHERIT. +// +// llgo:link (*Attr).Setinheritsched C.pthread_attr_setinheritsched +func (self *Attr) Setinheritsched(__inherit c.Int) c.Int { + return 0 +} + +// Return in *SCOPE the scheduling contention scope of *ATTR. +// +// llgo:link (*Attr).Getscope C.pthread_attr_getscope +func (self *Attr) Getscope(__scope *c.Int) c.Int { + return 0 +} + +// Set scheduling contention scope in *ATTR according to SCOPE. +// +// llgo:link (*Attr).Setscope C.pthread_attr_setscope +func (self *Attr) Setscope(__scope c.Int) c.Int { + return 0 +} + +// Return the previously set address for the stack. +// +// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr +func (self *Attr) GetStackAddr(__stackaddr *unsafe.Pointer) c.Int { return 0 } + +// Set the starting address of the stack of the thread to be created. +// Depending on whether the stack grows up or down the value must either +// be higher or lower than all the address in the memory block. The +// minimal size of the block must be PTHREAD_STACK_MIN. +// +// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr +func (self *Attr) SetStackAddr(__stackaddr unsafe.Pointer) c.Int { return 0 } + +// Return the currently used minimal stack size. +// +// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize +func (self *Attr) GetStackSize(__stacksize *c.SizeT) c.Int { return 0 } + +// Add information about the minimum stack size needed for the thread +// to be started. This size must never be less than PTHREAD_STACK_MIN +// and must also not exceed the system limits. +// +// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize +func (self *Attr) SetStackSize(__stacksize c.SizeT) c.Int { return 0 } + +// Return the previously set address for the stack. +// +// llgo:link (*Attr).Getstack C.pthread_attr_getstack +func (self *Attr) Getstack(__stackaddr *unsafe.Pointer, __stacksize *c.SizeT) c.Int { + return 0 +} + +// The following two interfaces are intended to replace the last two. They +// require setting the address as well as the size since only setting the +// address will make the implementation on some architectures impossible. +// +// llgo:link (*Attr).Setstack C.pthread_attr_setstack +func (self *Attr) Setstack(__stackaddr unsafe.Pointer, __stacksize c.SizeT) c.Int { + return 0 +} + +// Set the scheduling parameters for TARGET_THREAD according to POLICY +// and *PARAM. +// +//go:linkname Setschedparam C.pthread_setschedparam +func Setschedparam(__target_thread Thread, __policy c.Int, __param *llos.SchedParam) c.Int + +// Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. +// +//go:linkname Getschedparam C.pthread_getschedparam +func Getschedparam(__target_thread Thread, __policy *c.Int, __param *llos.SchedParam) c.Int + +// Set the scheduling priority for TARGET_THREAD. +// +//go:linkname Setschedprio C.pthread_setschedprio +func Setschedprio(__target_thread Thread, __prio c.Int) c.Int + +// Set cancelability state of current thread to STATE, returning old +// state in *OLDSTATE if OLDSTATE is not NULL. +// +//go:linkname Setcancelstate C.pthread_setcancelstate +func Setcancelstate(__state c.Int, __oldstate *c.Int) c.Int + +// Set cancellation state of current thread to TYPE, returning the old +// type in *OLDTYPE if OLDTYPE is not NULL. +// +//go:linkname Setcanceltype C.pthread_setcanceltype +func Setcanceltype(__type c.Int, __oldtype *c.Int) c.Int + +// Cancel THREAD immediately or at the next possibility. +// +//go:linkname Cancel C.pthread_cancel +func Cancel(__th Thread) c.Int + +// Test for pending cancellation for the current thread and terminate +// the thread as per pthread_exit(PTHREAD_CANCELED) if it has been +// cancelled. +// +//go:linkname Testcancel C.pthread_testcancel +func Testcancel() + +// llgo:link (*Key).Create C.pthread_key_create +func (self *Key) Create(__destr_function llcppgCallback9) c.Int { return 0 } + +// Destroy KEY. +// +// llgo:link Key.Delete C.pthread_key_delete +func (self Key) Delete() c.Int { return 0 } + +// Return current value of the thread-specific data slot identified by KEY. +// +// llgo:link Key.Get C.pthread_getspecific +func (self Key) Get() unsafe.Pointer { return nil } + +// Store POINTER in the thread-specific data slot identified by KEY. +// +// llgo:link Key.Set C.pthread_setspecific +func (self Key) Set(__pointer unsafe.Pointer) c.Int { return 0 } + +// Get ID of CPU-time clock for thread THREAD_ID. +// +//go:linkname Getcpuclockid C.pthread_getcpuclockid +func Getcpuclockid(__thread_id Thread, __clock_id *c.Int) c.Int + +//go:linkname Atfork C.pthread_atfork +func Atfork(__prepare llcppgCallback8, __parent llcppgCallback7, __child llcppgCallback6) c.Int + +type Attr struct { + _xgo_union [8]uint64 +} + +type AttrT = Attr + +type Key c.Uint diff --git a/c/pthread/llcppg.cfg b/c/pthread/llcppg.cfg new file mode 100644 index 00000000..75e27be3 --- /dev/null +++ b/c/pthread/llcppg.cfg @@ -0,0 +1,3 @@ +{ + "Dir": ".sysroot/include" +} diff --git a/c/pthread/llcppg.pub b/c/pthread/llcppg.pub index d0743f95..b7ad0c31 100644 --- a/c/pthread/llcppg.pub +++ b/c/pthread/llcppg.pub @@ -1,3 +1,10 @@ -T pthread_t Thread +D github.com/goplus/lib/c/os +D github.com/goplus/lib/c/signal +T _opaque_pthread_attr_t Attr T attr Attr +T pthread_attr_t AttrT +T pthread_jit_write_callback_t JitWriteCallbackT T pthread_key_t Key +T pthread_override_s OverrideS +T pthread_override_t OverrideT +T pthread_t Thread diff --git a/c/pthread/pthread.go b/c/pthread/pthread.go index f8a20312..ad698b09 100644 --- a/c/pthread/pthread.go +++ b/c/pthread/pthread.go @@ -40,72 +40,9 @@ type RoutineFunc func(c.Pointer) c.Pointer // Thread represents a POSIX thread. type Thread = *aThread -// The pthread_exit() function terminates the calling thread and -// returns a value via retval that (if the thread is joinable) is -// available to another thread in the same process that calls -// pthread_join(3). -// -// See https://man7.org/linux/man-pages/man3/pthread_exit.3.html -// -//go:linkname Exit C.pthread_exit -func Exit(retval c.Pointer) - -// The pthread_cancel() function sends a cancelation request to the -// thread thread. -// -// See https://man7.org/linux/man-pages/man3/pthread_cancel.3.html -// -//go:linkname Cancel C.pthread_cancel -func Cancel(thread Thread) c.Int - // ----------------------------------------------------------------------------- -// Attr represents a POSIX thread attributes. -type Attr struct { - Detached byte - SsSp *c.Char - SsSize uintptr -} - -// llgo:link (*Attr).Init C.pthread_attr_init -func (attr *Attr) Init() c.Int { return 0 } - -// llgo:link (*Attr).Destroy C.pthread_attr_destroy -func (attr *Attr) Destroy() c.Int { return 0 } - -// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate -func (attr *Attr) GetDetached(detached *c.Int) c.Int { return 0 } - -// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate -func (attr *Attr) SetDetached(detached c.Int) c.Int { return 0 } - -// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize -func (attr *Attr) GetStackSize(stackSize *uintptr) c.Int { return 0 } - -// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize -func (attr *Attr) SetStackSize(stackSize uintptr) c.Int { return 0 } - -// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr -func (attr *Attr) GetStackAddr(stackAddr *c.Pointer) c.Int { return 0 } - -// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr -func (attr *Attr) SetStackAddr(stackAddr c.Pointer) c.Int { return 0 } - // ----------------------------------------------------------------------------- // Thread Local Storage -type Key c.Uint - -// llgo:link (*Key).Create C.pthread_key_create -func (key *Key) Create(destructor func(c.Pointer)) c.Int { return 0 } - -// llgo:link Key.Delete C.pthread_key_delete -func (key Key) Delete() c.Int { return 0 } - -// llgo:link Key.Get C.pthread_getspecific -func (key Key) Get() c.Pointer { return nil } - -// llgo:link Key.Set C.pthread_setspecific -func (key Key) Set(value c.Pointer) c.Int { return __noop__() } - // ----------------------------------------------------------------------------- diff --git a/c/pthread/types_other.go b/c/pthread/types_other.go new file mode 100644 index 00000000..a70a7b0a --- /dev/null +++ b/c/pthread/types_other.go @@ -0,0 +1,14 @@ +//go:build !windows && !(darwin && arm64 && !ios) && !(linux && amd64 && !android) && !(linux && arm64 && !android) + +package pthread + +import "github.com/goplus/lib/c" + +// Attr represents POSIX thread attributes. +type Attr struct { + Detached byte + SsSp *c.Char + SsSize uintptr +} + +type Key c.Uint