1// Copyright 2011 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package runtime 6 7import "unsafe" 8 9type mOS struct { 10 waitsema uintptr // semaphore for parking on locks 11} 12 13func getProcID() uint64 { 14 return uint64(gettid()) 15} 16 17//extern malloc 18func libc_malloc(uintptr) unsafe.Pointer 19 20//go:noescape 21//extern sem_init 22func sem_init(sem *semt, pshared int32, value uint32) int32 23 24//go:noescape 25//extern sem_wait 26func sem_wait(sem *semt) int32 27 28//go:noescape 29//extern sem_post 30func sem_post(sem *semt) int32 31 32//go:noescape 33//extern sem_reltimedwait_np 34func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 35 36//go:nosplit 37func semacreate(mp *m) { 38 if mp.waitsema != 0 { 39 return 40 } 41 42 var sem *semt 43 44 // Call libc's malloc rather than malloc. This will 45 // allocate space on the C heap. We can't call malloc 46 // here because it could cause a deadlock. 47 sem = (*semt)(libc_malloc(unsafe.Sizeof(*sem))) 48 if sem_init(sem, 0, 0) != 0 { 49 throw("sem_init") 50 } 51 mp.waitsema = uintptr(unsafe.Pointer(sem)) 52} 53 54//go:nosplit 55func semasleep(ns int64) int32 { 56 _m_ := getg().m 57 if ns >= 0 { 58 var ts timespec 59 ts.setNsec(ns) 60 61 if sem_reltimedwait_np((*semt)(unsafe.Pointer(_m_.waitsema)), &ts) != 0 { 62 err := errno() 63 if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR { 64 return -1 65 } 66 throw("sem_reltimedwait_np") 67 } 68 return 0 69 } 70 for { 71 r1 := sem_wait((*semt)(unsafe.Pointer(_m_.waitsema))) 72 if r1 == 0 { 73 break 74 } 75 if errno() == _EINTR { 76 continue 77 } 78 throw("sem_wait") 79 } 80 return 0 81} 82 83//go:nosplit 84func semawakeup(mp *m) { 85 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 { 86 throw("sem_post") 87 } 88} 89