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

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



Thanks again. 

Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>

On 26.09.19, 17:32, "Charalampos Mainas" <Charalampos.Mainas@xxxxxxxxx> wrote:

    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®.