summaryrefslogtreecommitdiff
path: root/vendor/modernc.org/libc/pthread_musl.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/libc/pthread_musl.go')
-rw-r--r--vendor/modernc.org/libc/pthread_musl.go121
1 files changed, 51 insertions, 70 deletions
diff --git a/vendor/modernc.org/libc/pthread_musl.go b/vendor/modernc.org/libc/pthread_musl.go
index 01fa300f6..c051945af 100644
--- a/vendor/modernc.org/libc/pthread_musl.go
+++ b/vendor/modernc.org/libc/pthread_musl.go
@@ -22,14 +22,26 @@ type pthreadCleanupItem struct {
routine, arg uintptr
}
-// C version is 40 bytes (64b) and 24 bytes (32b).
-type pthreadMutex struct { // 64b 32b
- sync.Mutex // 0 8 0 8
- count int32 // 8 4 8 4
- mType uint32 // 12 4 12 4
- outer sync.Mutex // 16 8 16 8
- owner int32 // 24 4 24 4
- // 28 28
+// C original, unpatched version
+//
+// include/alltypes.h.in:86:TYPEDEF struct {
+// union {
+// int __i[sizeof(long)==8?10:6];
+// volatile int __vi[sizeof(long)==8?10:6];
+// volatile void *volatile __p[sizeof(long)==8?5:6];
+// } __u;
+// } pthread_mutex_t;
+
+//TODO(jnml) can remove __ccgo_room patches now.
+
+// We overlay the C version with our version below. It must not be larger than
+// the C version.
+type pthreadMutex struct { // gc 64b 32b | tinygo 64b 32b
+ sync.Mutex // 0 8 0 4 | 0 16 0 8
+ count int32 // 8 4 4 4 | 16 4 8 4
+ typ uint32 // 12 4 8 4 | 20 4 12 4
+ owner int32 // 16 4 12 4 | 24 4 16 4
+ // 20 16 | 28 20
}
type pthreadConds struct {
@@ -39,7 +51,6 @@ type pthreadConds struct {
var (
// Ensure there's enough space for unsafe type conversions.
- _ [unsafe.Sizeof(sync.Mutex{}) - __CCGO_SIZEOF_GO_MUTEX]byte
_ [unsafe.Sizeof(Tpthread_mutex_t{}) - unsafe.Sizeof(pthreadMutex{})]byte
_ [unsafe.Sizeof(Tpthread_attr_t{}) - unsafe.Sizeof(pthreadAttr{})]byte
@@ -255,103 +266,75 @@ func Xpthread_self(tls *TLS) uintptr {
func Xpthread_mutex_init(tls *TLS, m, a uintptr) int32 {
*(*Tpthread_mutex_t)(unsafe.Pointer(m)) = Tpthread_mutex_t{}
if a != 0 {
- (*pthreadMutex)(unsafe.Pointer(m)).mType = (*Tpthread_mutexattr_t)(unsafe.Pointer(a)).F__attr
+ (*pthreadMutex)(unsafe.Pointer(m)).typ = (*Tpthread_mutexattr_t)(unsafe.Pointer(a)).F__attr
}
return 0
}
-func Xpthread_mutex_destroy(tls *TLS, mutex uintptr) int32 {
+func Xpthread_mutex_destroy(tls *TLS, m uintptr) int32 {
+ *(*Tpthread_mutex_t)(unsafe.Pointer(m)) = Tpthread_mutex_t{}
return 0
}
func Xpthread_mutex_lock(tls *TLS, m uintptr) int32 {
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Lock()
- owner := (*pthreadMutex)(unsafe.Pointer(m)).owner
- typ := (*pthreadMutex)(unsafe.Pointer(m)).mType
- switch typ {
+ switch typ := (*pthreadMutex)(unsafe.Pointer(m)).typ; typ {
case PTHREAD_MUTEX_NORMAL:
- (*pthreadMutex)(unsafe.Pointer(m)).owner = tls.ID
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
(*pthreadMutex)(unsafe.Pointer(m)).Lock()
+ return 0
case PTHREAD_MUTEX_RECURSIVE:
- switch owner {
- case 0:
+ if atomic.CompareAndSwapInt32(&((*pthreadMutex)(unsafe.Pointer(m)).owner), 0, tls.ID) {
(*pthreadMutex)(unsafe.Pointer(m)).count = 1
- (*pthreadMutex)(unsafe.Pointer(m)).owner = tls.ID
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
(*pthreadMutex)(unsafe.Pointer(m)).Lock()
return 0
- case tls.ID:
+ }
+
+ if atomic.LoadInt32(&((*pthreadMutex)(unsafe.Pointer(m)).owner)) == tls.ID {
(*pthreadMutex)(unsafe.Pointer(m)).count++
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
return 0
- default:
- wait:
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
+ }
+
+ for {
(*pthreadMutex)(unsafe.Pointer(m)).Lock()
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Lock()
- if (*pthreadMutex)(unsafe.Pointer(m)).owner != 0 {
- goto wait
+ if atomic.CompareAndSwapInt32(&((*pthreadMutex)(unsafe.Pointer(m)).owner), 0, tls.ID) {
+ (*pthreadMutex)(unsafe.Pointer(m)).count = 1
+ return 0
}
- (*pthreadMutex)(unsafe.Pointer(m)).count = 1
- (*pthreadMutex)(unsafe.Pointer(m)).owner = tls.ID
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
- return 0
+ (*pthreadMutex)(unsafe.Pointer(m)).Unlock()
}
default:
- panic(todo("typ=%v", typ))
+ panic(todo("", typ))
}
- return 0
}
func Xpthread_mutex_trylock(tls *TLS, m uintptr) int32 {
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Lock()
- owner := (*pthreadMutex)(unsafe.Pointer(m)).owner
- typ := (*pthreadMutex)(unsafe.Pointer(m)).mType
- switch typ {
+ switch typ := (*pthreadMutex)(unsafe.Pointer(m)).typ; typ {
case PTHREAD_MUTEX_NORMAL:
- if owner != 0 {
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
- return EBUSY
+ if (*pthreadMutex)(unsafe.Pointer(m)).TryLock() {
+ return 0
}
- (*pthreadMutex)(unsafe.Pointer(m)).owner = tls.ID
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
- (*pthreadMutex)(unsafe.Pointer(m)).Lock()
- return 0
+ return EBUSY
default:
panic(todo("typ=%v", typ))
}
}
func Xpthread_mutex_unlock(tls *TLS, m uintptr) int32 {
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Lock()
- count := (*pthreadMutex)(unsafe.Pointer(m)).count
- owner := (*pthreadMutex)(unsafe.Pointer(m)).owner
- typ := (*pthreadMutex)(unsafe.Pointer(m)).mType
- switch typ {
+ switch typ := (*pthreadMutex)(unsafe.Pointer(m)).typ; typ {
case PTHREAD_MUTEX_NORMAL:
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
(*pthreadMutex)(unsafe.Pointer(m)).Unlock()
return 0
case PTHREAD_MUTEX_RECURSIVE:
- switch owner {
- case tls.ID:
- switch count {
- case 1:
- (*pthreadMutex)(unsafe.Pointer(m)).owner = 0
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
- (*pthreadMutex)(unsafe.Pointer(m)).Unlock()
- return 0
- default:
- (*pthreadMutex)(unsafe.Pointer(m)).count--
- (*pthreadMutex)(unsafe.Pointer(m)).outer.Unlock()
- return 0
- }
- default:
- panic(todo("", owner, tls.ID))
+ if atomic.LoadInt32(&((*pthreadMutex)(unsafe.Pointer(m)).owner)) != tls.ID {
+ return EPERM
}
+
+ if atomic.AddInt32(&((*pthreadMutex)(unsafe.Pointer(m)).count), -1) == 0 {
+ atomic.StoreInt32(&((*pthreadMutex)(unsafe.Pointer(m)).owner), 0)
+ (*pthreadMutex)(unsafe.Pointer(m)).Unlock()
+ }
+ return 0
default:
panic(todo("", typ))
}
@@ -404,9 +387,8 @@ func Xpthread_cond_timedwait(tls *TLS, c, m, ts uintptr) (r int32) {
}
}()
- switch typ := (*pthreadMutex)(unsafe.Pointer(m)).mType; typ {
+ switch typ := (*pthreadMutex)(unsafe.Pointer(m)).typ; typ {
case PTHREAD_MUTEX_NORMAL:
- (*pthreadMutex)(unsafe.Pointer(m)).owner = 0
(*pthreadMutex)(unsafe.Pointer(m)).Unlock()
select {
case <-ch:
@@ -414,7 +396,6 @@ func Xpthread_cond_timedwait(tls *TLS, c, m, ts uintptr) (r int32) {
case <-to:
r = ETIMEDOUT
}
- (*pthreadMutex)(unsafe.Pointer(m)).owner = tls.ID
(*pthreadMutex)(unsafe.Pointer(m)).Lock()
return r
default: