]> xenbits.xensource.com Git - unikraft/libs/libgo.git/commitdiff
Use semaphores instead of futexes
authorCharalampos Mainas <Charalampos.Mainas@neclab.eu>
Thu, 26 Sep 2019 15:31:36 +0000 (17:31 +0200)
committerFelipe Huici <felipe.huici@neclab.eu>
Fri, 27 Sep 2019 08:51:17 +0000 (10:51 +0200)
Go uses futexes for locking in linux but they are not implemented in
Unikraft. As a result we need to switch to semaphores.

Signed-off-by: Charalampos Mainas <Charalampos.Mainas@neclab.eu>
Reviewed-by: Felipe Huici <felipe.huici@neclab.eu>
packages.uk
patches/0006-libgo-Use-semaphores-instead-of-futexes.patch [new file with mode: 0644]

index 60f0ef192dd3d861fc9ea59af3f45b8fd1150374..ec974086e5ef603b2f79aee5d69bef6fb0c2c7f6 100644 (file)
@@ -80,7 +80,7 @@ $(LIBGO_BUILD)/image/color.o: $(LIBGO_EXTRACTED)/go/image/color/color.go $(LIBGO
        mkdir -p $(dir $@) && \
        $(GOC) $(LIBGO_GOFLAGS) -c -fgo-pkgpath=image/color $^ -o $@ && \
        objcopy -j .go_export $@ $(@:.o=.gox))
-$(LIBGO_BUILD)/runtime.o: $(LIBGO_EXTRACTED)/go/runtime/alg.go $(LIBGO_EXTRACTED)/go/runtime/cgo_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/chan.go $(LIBGO_EXTRACTED)/go/runtime/compiler.go $(LIBGO_EXTRACTED)/go/runtime/cpuprof.go $(LIBGO_EXTRACTED)/go/runtime/cputicks.go $(LIBGO_EXTRACTED)/go/runtime/debug.go $(LIBGO_EXTRACTED)/go/runtime/env_posix.go $(LIBGO_EXTRACTED)/go/runtime/error.go $(LIBGO_EXTRACTED)/go/runtime/extern.go $(LIBGO_EXTRACTED)/go/runtime/ffi.go $(LIBGO_EXTRACTED)/go/runtime/hash64.go $(LIBGO_EXTRACTED)/go/runtime/hashmap.go $(LIBGO_EXTRACTED)/go/runtime/hashmap_fast.go $(LIBGO_EXTRACTED)/go/runtime/iface.go $(LIBGO_EXTRACTED)/go/runtime/lfstack.go $(LIBGO_EXTRACTED)/go/runtime/lfstack_64bit.go $(LIBGO_EXTRACTED)/go/runtime/lock_futex.go $(LIBGO_EXTRACTED)/go/runtime/mcache.go $(LIBGO_EXTRACTED)/go/runtime/mprof.go $(LIBGO_EXTRACTED)/go/runtime/msan0.go $(LIBGO_EXTRACTED)/go/runtime/mstats.go $(LIBGO_EXTRACTED)/go/runtime/netpoll.go $(LIBGO_EXTRACTED)/go/runtime/netpoll_epoll.go $(LIBGO_EXTRACTED)/go/runtime/os_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/os_linux.go $(LIBGO_EXTRACTED)/go/runtime/panic.go $(LIBGO_EXTRACTED)/go/runtime/print.go $(LIBGO_EXTRACTED)/go/runtime/proc.go $(LIBGO_EXTRACTED)/go/runtime/race0.go $(LIBGO_EXTRACTED)/go/runtime/rdebug.go $(LIBGO_EXTRACTED)/go/runtime/runtime.go $(LIBGO_EXTRACTED)/go/runtime/runtime1.go $(LIBGO_EXTRACTED)/go/runtime/runtime2.go $(LIBGO_EXTRACTED)/go/runtime/select.go $(LIBGO_EXTRACTED)/go/runtime/sema.go $(LIBGO_EXTRACTED)/go/runtime/signal_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/signal_sighandler.go $(LIBGO_EXTRACTED)/go/runtime/signal_unix.go $(LIBGO_EXTRACTED)/go/runtime/sigqueue.go $(LIBGO_EXTRACTED)/go/runtime/sizeclasses.go $(LIBGO_EXTRACTED)/go/runtime/slice.go $(LIBGO_EXTRACTED)/go/runtime/string.go $(LIBGO_EXTRACTED)/go/runtime/stubs.go $(LIBGO_EXTRACTED)/go/runtime/stubs2.go $(LIBGO_EXTRACTED)/go/runtime/symtab.go $(LIBGO_EXTRACTED)/go/runtime/time.go $(LIBGO_EXTRACTED)/go/runtime/trace.go $(LIBGO_EXTRACTED)/go/runtime/traceback_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/type.go $(LIBGO_EXTRACTED)/go/runtime/typekind.go $(LIBGO_EXTRACTED)/go/runtime/unaligned1.go $(LIBGO_EXTRACTED)/go/runtime/utf8.go $(LIBGO_EXTRACTED)/go/runtime/write_err.go $(LIBGO_BASE)/generated/runtime_sysinfo.go $(LIBGO_BASE)/generated/sigtab.go
+$(LIBGO_BUILD)/runtime.o: $(LIBGO_EXTRACTED)/go/runtime/alg.go $(LIBGO_EXTRACTED)/go/runtime/cgo_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/chan.go $(LIBGO_EXTRACTED)/go/runtime/compiler.go $(LIBGO_EXTRACTED)/go/runtime/cpuprof.go $(LIBGO_EXTRACTED)/go/runtime/cputicks.go $(LIBGO_EXTRACTED)/go/runtime/debug.go $(LIBGO_EXTRACTED)/go/runtime/env_posix.go $(LIBGO_EXTRACTED)/go/runtime/error.go $(LIBGO_EXTRACTED)/go/runtime/extern.go $(LIBGO_EXTRACTED)/go/runtime/ffi.go $(LIBGO_EXTRACTED)/go/runtime/hash64.go $(LIBGO_EXTRACTED)/go/runtime/hashmap.go $(LIBGO_EXTRACTED)/go/runtime/hashmap_fast.go $(LIBGO_EXTRACTED)/go/runtime/iface.go $(LIBGO_EXTRACTED)/go/runtime/lfstack.go $(LIBGO_EXTRACTED)/go/runtime/lfstack_64bit.go $(LIBGO_EXTRACTED)/go/runtime/lock_sema.go $(LIBGO_EXTRACTED)/go/runtime/mcache.go $(LIBGO_EXTRACTED)/go/runtime/mprof.go $(LIBGO_EXTRACTED)/go/runtime/msan0.go $(LIBGO_EXTRACTED)/go/runtime/mstats.go $(LIBGO_EXTRACTED)/go/runtime/netpoll.go $(LIBGO_EXTRACTED)/go/runtime/netpoll_epoll.go $(LIBGO_EXTRACTED)/go/runtime/os_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/os_linux.go $(LIBGO_EXTRACTED)/go/runtime/panic.go $(LIBGO_EXTRACTED)/go/runtime/print.go $(LIBGO_EXTRACTED)/go/runtime/proc.go $(LIBGO_EXTRACTED)/go/runtime/race0.go $(LIBGO_EXTRACTED)/go/runtime/rdebug.go $(LIBGO_EXTRACTED)/go/runtime/runtime.go $(LIBGO_EXTRACTED)/go/runtime/runtime1.go $(LIBGO_EXTRACTED)/go/runtime/runtime2.go $(LIBGO_EXTRACTED)/go/runtime/select.go $(LIBGO_EXTRACTED)/go/runtime/sema.go $(LIBGO_EXTRACTED)/go/runtime/signal_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/signal_sighandler.go $(LIBGO_EXTRACTED)/go/runtime/signal_unix.go $(LIBGO_EXTRACTED)/go/runtime/sigqueue.go $(LIBGO_EXTRACTED)/go/runtime/sizeclasses.go $(LIBGO_EXTRACTED)/go/runtime/slice.go $(LIBGO_EXTRACTED)/go/runtime/string.go $(LIBGO_EXTRACTED)/go/runtime/stubs.go $(LIBGO_EXTRACTED)/go/runtime/stubs2.go $(LIBGO_EXTRACTED)/go/runtime/symtab.go $(LIBGO_EXTRACTED)/go/runtime/time.go $(LIBGO_EXTRACTED)/go/runtime/trace.go $(LIBGO_EXTRACTED)/go/runtime/traceback_gccgo.go $(LIBGO_EXTRACTED)/go/runtime/type.go $(LIBGO_EXTRACTED)/go/runtime/typekind.go $(LIBGO_EXTRACTED)/go/runtime/unaligned1.go $(LIBGO_EXTRACTED)/go/runtime/utf8.go $(LIBGO_EXTRACTED)/go/runtime/write_err.go $(LIBGO_BASE)/generated/runtime_sysinfo.go $(LIBGO_BASE)/generated/sigtab.go
        $(call verbose_cmd,GO,libgo: $(notdir $@), cd $(LIBGO_EXTRACTED) && \
        $(GOC) $(LIBGO_GOFLAGS) -c -fgo-pkgpath=runtime -fgo-c-header=$(LIBGO_BASE)/generated/runtime.inc.tmp -fgo-compiling-runtime $^ -o $@ && \
        objcopy -j .go_export $@ $(@:.o=.gox))
diff --git a/patches/0006-libgo-Use-semaphores-instead-of-futexes.patch b/patches/0006-libgo-Use-semaphores-instead-of-futexes.patch
new file mode 100644 (file)
index 0000000..fdc12e3
--- /dev/null
@@ -0,0 +1,131 @@
+From ad52a67ca084d40768ad8fdf492ee26f41902670 Mon Sep 17 00:00:00 2001
+From: Charalampos Mainas <Charalampos.Mainas@neclab.eu>
+Date: Fri, 6 Sep 2019 12:08:53 +0200
+Subject: [PATCH] Use semaphores instead of futexes
+
+futexes are not implemented on Unikraft. In libgo there are some other
+targets (like openbsd) which use semaphores instead of futexes.
+Following the same approach as in these targets, with this patch 
+locking is done using semaphores.
+
+---
+ libgo/go/runtime/os_linux.go | 99 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 96 insertions(+), 3 deletions(-)
+
+diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go
+index ad334869e..775f34859 100644
+--- a/libgo/go/runtime/os_linux.go
++++ b/libgo/go/runtime/os_linux.go
+@@ -9,9 +9,9 @@ import (
+       "unsafe"
+ )
+-type mOS struct {
+-      unused byte
+-}
++//type mOS struct {
++//    unused byte
++//}
+ func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32 {
+       return int32(syscall(_SYS_futex, uintptr(addr), uintptr(op), uintptr(val), uintptr(ts), uintptr(addr2), uintptr(val3)))
+@@ -169,3 +169,96 @@ func sysauxv(auxv []uintptr) int {
+ // Temporary for gccgo until we port mem_GOOS.go.
+ var addrspace_vec [1]byte
++
++// 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.
++
++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: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))
++              ns += nanotime()
++              if sys.PtrSize == 8 {
++                      ts.set_sec(ns / 1000000000)
++                      ts.set_nsec(int32(ns % 1000000000))
++              } else {
++                      ts.tv_nsec = 0
++                      ts.set_sec(int64(timediv(ns, 1000000000, (*int32)(unsafe.Pointer(&ts.tv_nsec)))))
++              }
++              //var nsec int32
++              //ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
++              //ts.set_nsec(nsec)
++
++              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")
++      }
++}
+-- 
+2.17.1
+