Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
runtime: netpoll and semaphores for AIX
semaphore implementation based on Solaris implementation in libgo/go/runtime/os_solaris.go netpoll is just a stub to avoid build failure on AIX. Issue golang/go#19200 Change-Id: Iac0712e01ae6f5208852489d542a9cad41f6c50e Reviewed-on: https://go-review.googlesource.com/37966 Reviewed-by: Ian Lance Taylor <iant@golang.org>
- Loading branch information
1 parent
a0275c0
commit 29b190f
Showing
2 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2017 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. | ||
|
||
// Fake network poller for AIX | ||
// TODO : this is just stubs to allow building, implementation required | ||
|
||
package runtime | ||
|
||
func netpollinit() { | ||
} | ||
|
||
func netpollopen(fd uintptr, pd *pollDesc) int32 { | ||
return 0 | ||
} | ||
|
||
func netpollclose(fd uintptr) int32 { | ||
return 0 | ||
} | ||
|
||
func netpollarm(pd *pollDesc, mode int) { | ||
} | ||
|
||
func netpoll(block bool) *g { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright 2017 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_timedwait | ||
func sem_timedwait(sem *semt, timeout *timespec) int32 | ||
|
||
//go:noescape | ||
//extern clock_gettime | ||
func clock_gettime(clock_id int64, 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 { | ||
const CLOCK_REALTIME int64 = 9 | ||
var ts timespec | ||
|
||
if clock_gettime(CLOCK_REALTIME, &ts) != 0 { | ||
throw("clock_gettime") | ||
} | ||
ts.tv_sec += timespec_sec_t(ns / 1000000000) | ||
ts.tv_nsec += timespec_nsec_t((int64(ts.tv_nsec) + ns) % 1000000000) | ||
if ts.tv_nsec >= 1000000000 { | ||
ts.tv_sec += timespec_sec_t(1) | ||
ts.tv_nsec -= timespec_nsec_t(1000000000) | ||
} | ||
|
||
if sem_timedwait((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 { | ||
err := errno() | ||
if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR { | ||
return -1 | ||
} | ||
throw("sem_timedwait") | ||
} | ||
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") | ||
} | ||
} |