mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			86 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2011 The Go Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package runtime
 | 
						|
 | 
						|
import "unsafe"
 | 
						|
 | 
						|
type mOS struct {
 | 
						|
	waitsema uintptr // semaphore for parking on locks
 | 
						|
}
 | 
						|
 | 
						|
//extern malloc
 | 
						|
func libc_malloc(uintptr) unsafe.Pointer
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern sem_init
 | 
						|
func sem_init(sem *semt, pshared int32, value uint32) int32
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern sem_wait
 | 
						|
func sem_wait(sem *semt) int32
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern sem_post
 | 
						|
func sem_post(sem *semt) int32
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern sem_reltimedwait_np
 | 
						|
func sem_reltimedwait_np(sem *semt, timeout *timespec) int32
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semacreate(mp *m) {
 | 
						|
	if mp.mos.waitsema != 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	var sem *semt
 | 
						|
 | 
						|
	// Call libc's malloc rather than malloc. This will
 | 
						|
	// allocate space on the C heap. We can't call malloc
 | 
						|
	// here because it could cause a deadlock.
 | 
						|
	sem = (*semt)(libc_malloc(unsafe.Sizeof(*sem)))
 | 
						|
	if sem_init(sem, 0, 0) != 0 {
 | 
						|
		throw("sem_init")
 | 
						|
	}
 | 
						|
	mp.mos.waitsema = uintptr(unsafe.Pointer(sem))
 | 
						|
}
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semasleep(ns int64) int32 {
 | 
						|
	_m_ := getg().m
 | 
						|
	if ns >= 0 {
 | 
						|
		var ts timespec
 | 
						|
		ts.set_sec(ns / 1000000000)
 | 
						|
		ts.set_nsec(int32(ns % 1000000000))
 | 
						|
 | 
						|
		if sem_reltimedwait_np((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 {
 | 
						|
			err := errno()
 | 
						|
			if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR {
 | 
						|
				return -1
 | 
						|
			}
 | 
						|
			throw("sem_reltimedwait_np")
 | 
						|
		}
 | 
						|
		return 0
 | 
						|
	}
 | 
						|
	for {
 | 
						|
		r1 := sem_wait((*semt)(unsafe.Pointer(_m_.mos.waitsema)))
 | 
						|
		if r1 == 0 {
 | 
						|
			break
 | 
						|
		}
 | 
						|
		if errno() == _EINTR {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		throw("sem_wait")
 | 
						|
	}
 | 
						|
	return 0
 | 
						|
}
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semawakeup(mp *m) {
 | 
						|
	if sem_post((*semt)(unsafe.Pointer(mp.mos.waitsema))) != 0 {
 | 
						|
		throw("sem_post")
 | 
						|
	}
 | 
						|
}
 |