[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT/LIBGO PATCH 09/11] Use semaphores instead of futexes



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@xxxxxxxxx>
---
 packages.uk                                   |   2 +-
 ...go-Use-semaphores-instead-of-futexes.patch | 131 ++++++++++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100644 patches/0006-libgo-Use-semaphores-instead-of-futexes.patch

diff --git a/packages.uk b/packages.uk
index 60f0ef1..ec97408 100644
--- a/packages.uk
+++ b/packages.uk
@@ -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
index 0000000..fdc12e3
--- /dev/null
+++ b/patches/0006-libgo-Use-semaphores-instead-of-futexes.patch
@@ -0,0 +1,131 @@
+From ad52a67ca084d40768ad8fdf492ee26f41902670 Mon Sep 17 00:00:00 2001
+From: Charalampos Mainas <Charalampos.Mainas@xxxxxxxxx>
+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
+
-- 
2.17.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.