Skip to content

Commit

Permalink
runtime: netpoll and semaphores for AIX
Browse files Browse the repository at this point in the history
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
MatthieuSarter authored and ianlancetaylor committed Mar 10, 2017
1 parent a0275c0 commit 29b190f
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
26 changes: 26 additions & 0 deletions libgo/go/runtime/netpoll_aix.go
@@ -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
}
98 changes: 98 additions & 0 deletions libgo/go/runtime/os_aix.go
@@ -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")
}
}

0 comments on commit 29b190f

Please sign in to comment.