mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			77 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			1.8 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 (
 | 
						|
	"runtime/internal/atomic"
 | 
						|
	"unsafe"
 | 
						|
)
 | 
						|
 | 
						|
type mOS struct {
 | 
						|
	waitsemacount uint32
 | 
						|
}
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern thrsleep
 | 
						|
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32
 | 
						|
 | 
						|
//go:noescape
 | 
						|
//extern thrwakeup
 | 
						|
func thrwakeup(ident uintptr, n int32) int32
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semacreate(mp *m) {
 | 
						|
}
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semasleep(ns int64) int32 {
 | 
						|
	_g_ := getg()
 | 
						|
 | 
						|
	// Compute sleep deadline.
 | 
						|
	var tsp *timespec
 | 
						|
	if ns >= 0 {
 | 
						|
		var ts timespec
 | 
						|
		var nsec int32
 | 
						|
		ns += nanotime()
 | 
						|
		ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
 | 
						|
		ts.set_nsec(nsec)
 | 
						|
		tsp = &ts
 | 
						|
	}
 | 
						|
 | 
						|
	for {
 | 
						|
		v := atomic.Load(&_g_.m.mos.waitsemacount)
 | 
						|
		if v > 0 {
 | 
						|
			if atomic.Cas(&_g_.m.mos.waitsemacount, v, v-1) {
 | 
						|
				return 0 // semaphore acquired
 | 
						|
			}
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// Sleep until woken by semawakeup or timeout; or abort if waitsemacount != 0.
 | 
						|
		//
 | 
						|
		// From OpenBSD's __thrsleep(2) manual:
 | 
						|
		// "The abort argument, if not NULL, points to an int that will
 | 
						|
		// be examined [...] immediately before blocking. If that int
 | 
						|
		// is non-zero then __thrsleep() will immediately return EINTR
 | 
						|
		// without blocking."
 | 
						|
		ret := thrsleep(uintptr(unsafe.Pointer(&_g_.m.mos.waitsemacount)), _CLOCK_MONOTONIC, tsp, 0, &_g_.m.mos.waitsemacount)
 | 
						|
		if ret == _EWOULDBLOCK {
 | 
						|
			return -1
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
//go:nosplit
 | 
						|
func semawakeup(mp *m) {
 | 
						|
	atomic.Xadd(&mp.mos.waitsemacount, 1)
 | 
						|
	ret := thrwakeup(uintptr(unsafe.Pointer(&mp.mos.waitsemacount)), 1)
 | 
						|
	if ret != 0 && ret != _ESRCH {
 | 
						|
		// semawakeup can be called on signal stack.
 | 
						|
		systemstack(func() {
 | 
						|
			print("thrwakeup addr=", &mp.mos.waitsemacount, " sem=", mp.mos.waitsemacount, " ret=", ret, "\n")
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |