Skip to content

Commit

Permalink
update libs
Browse files Browse the repository at this point in the history
  • Loading branch information
drswinghead committed Feb 26, 2020
1 parent 7a87464 commit 703d101
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 19 deletions.
14 changes: 14 additions & 0 deletions xgo/builtin/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,20 @@ func (s string) index(sep string) int {
return res
}

func (s string) rindex(sep string) int {
res := -1
slen := s.len
seplen := sep.len
for i := slen - seplen; i >= 0; i-- {
if s[i:i+seplen] == sep {
res = i
break
}
}

return res
}

func (s string) left(sep string) string {
pos := s.index(sep)
if pos < 0 {
Expand Down
2 changes: 1 addition & 1 deletion xgo/runtime/libc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package libc
package runtime

/*
*/
Expand Down
143 changes: 135 additions & 8 deletions xgo/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,163 @@ package runtime
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <gc.h>
static void cygo_pmutex_foo() {}
typedef int (*pmutex_lock_t)(pthread_mutex_t *mutex);
extern pmutex_lock_t pmutex_lock_f;
typedef int (*pmutex_unlock_t)(pthread_mutex_t *mutex);
extern pmutex_unlock_t pmutex_unlock_f;
void cygo_pmutex_lock(voidptr mu) { pmutex_lock_f(mu); }
void cygo_pmutex_unlock(voidptr mu) { pmutex_unlock_f(mu); }
typedef int (*pcond_wait_t)(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
extern pcond_wait_t pcond_wait_f;
typedef int (*pcond_signal_t)(pthread_cond_t *cond);
extern pcond_signal_t pcond_signal_f;
typedef int (*pcond_broadcast_t)(pthread_cond_t *cond);
extern pcond_broadcast_t pcond_broadcast_f;
void cygo_pcond_wait(voidptr cd, voidptr mu) { pcond_wait_f(cd, mu); }
void cygo_pcond_signal(voidptr cd) { pcond_signal_f(cd); }
void cygo_pcond_broadcast(voidptr cd) { pcond_broadcast_f(cd); }
int cygo_pthread_create(voidptr h, voidptr fn, voidptr arg) {
return GC_pthread_create(h, 0, fn, arg);
}
int cygo_pthread_join(pthread_t h, voidptr* retval) {
return GC_pthread_join(h, retval);
}
int cygo_pthread_detach(pthread_t h) { return GC_pthread_detach(h); }
*/
import "C"

type Thread struct {
// it's realy raw mutex, without hook, internal use
type pmutex struct {
obj C.pthread_mutex_t
}

func newpmutex() *pmutex {
mu := &pmutex{}
return mu
}
func (mu *pmutex) foo() {
// C.cygo_pmutex_foo() // TODO compiler cparser
}
func (mu *pmutex) lock() { C.cygo_pmutex_lock(&mu.obj) }
func (mu *pmutex) unlock() { C.cygo_pmutex_unlock(&mu.obj) }

///
type pcond struct {
obj C.pthread_cond_t
}

func newpcond() *pcond {
cd := &pcond{}
return cd
}

func (cd *pcond) wait(mu *pmutex) {
C.cygo_pcond_wait(&cd.obj, &mu.obj)
}
func (cd *pcond) signal() {
C.cygo_pcond_signal(&cd.obj)
}
func (cd *pcond) broadcast(mu *pmutex) {
C.cygo_pcond_broadcast(&cd.obj)
}

///
type pthread struct {
handle C.pthread_t
state int
mu *pmutex
cd *pcond

fnptr func(arg voidptr) voidptr
fnptr func(arg *pthread) voidptr
fnarg voidptr
}

func NewThread(fnptr func(arg voidptr) voidptr, fnarg voidptr) *Thread {
thr := &Thread{}
func newpthread(fnptr func(arg *pthread) voidptr, fnarg voidptr) *pthread {
thr := &pthread{}
thr.fnptr = fnptr
thr.fnarg = fnarg

thr.mu = newpmutex()
thr.cd = newpcond()
return thr
}

func (thr *Thread) start() {
// not used, just demo
func pthread_proc_demo(thr *pthread) voidptr {
// rv := thr.fnptr(thr.fnarg) // TODO compiler
fnptr := thr.fnptr
rv := fnptr(thr.fnarg)
return rv
}

func (thr *pthread) start() {
thr.mu.lock()
state := thr.state
if state == 0 {
thr.state = 1
}
thr.mu.unlock()
if state > 0 {
println("pthread already started")
return
}
rv := C.cygo_pthread_create(&thr.handle, thr.fnptr, thr)
}
func (thr *pthread) getarg() voidptr { return thr.fnarg }

func (thr *pthread) join() int {
rv := C.cygo_pthread_join(thr.handle, nil)
thr.state = 0
return rv
}
func (thr *pthread) detach() int {
rv := C.cygo_pthread_detach(thr.handle)
return rv
}

func (thr *Thread) suspend() {
// only callable in thr.fnptr
func (thr *pthread) suspend() {
rv := C.pthread_self()
if rv != thr.handle {
println("cannot suspend thread in other thread")
return
}

thr.mu.lock()
thr.state++
thr.cd.wait(thr.mu)
thr.state--
thr.mu.unlock()
}

func (thr *Thread) resume() {
// not callable in thr.fnptr
func (thr *pthread) resume() {
rv := C.pthread_self()
if rv == thr.handle {
println("cannot resume thread in same thread")
return
}

thr.mu.lock()
state := thr.state
if state == 2 {
thr.cd.signal()
} else if state == 1 {
println("pthread not suspended")
thr.cd.signal()
} else {
println("pthread not started")
}
thr.mu.unlock()
}

func keep() {}
func Keep() {}
4 changes: 2 additions & 2 deletions xgo/xlog/backtrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ func init() {
func lazyinit_dwarf() {
if dwdbg == nil {
newed := false
globmu.Lock()
globmu.lock()
if dwdbg == nil {
newed = true
dwdbg = dwarf.NewDwarf()
}
globmu.Unlock()
globmu.unlock()
if newed {
// dwdbg.Open("./ocgui")
dwdbg.OpenSelf()
Expand Down
13 changes: 13 additions & 0 deletions xgo/xos/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ func Readlink(s string) string {
}
return gostringn(respath.ptr, rv)
}
func Wkdir() string {
var s string
var buf voidptr
for blen := 8; blen <= PATH_MAX; blen *= 2 {
buf = realloc3(buf, blen)
rv := C.getcwd(buf, blen)
if rv != nil {
s = gostring(buf)
break
}
}
return s
}

func Umask(mask int) int {
rv := C.umask(0)
Expand Down
32 changes: 24 additions & 8 deletions xgo/xsync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,34 @@ func init() {
}
}

/// hook and yield public use
type Mutex struct {
// TODO compilerd to voidptr lock, and failed then
// if in somewhere have use of C.pthread_mutex_t, then it's works again
// oh, it is a union
lock C.pthread_mutex_t
obj C.pthread_mutex_t
}

func (mu *Mutex) Lock() {
C.pthread_mutex_lock(&mu.lock)
func NewMutex() *Mutex {
mu := &Mutex{}
return mu
}
func (mu *Mutex) Unlock() {
C.pthread_mutex_unlock(&mu.lock)
func (mu *Mutex) lock() { C.pthread_mutex_lock(&mu.obj) }
func (mu *Mutex) unlock() { C.pthread_mutex_unlock(&mu.obj) }

type Cond struct {
obj C.pthread_cond_t
}

func NewCond() *Cond {
cd := &Cond{}
return cd
}
func (cd *Cond) wait(mu *Mutex) {
C.pthread_cond_wait(&cd.obj, &mu.obj)
}
func (cd *Cond) signal() {
C.pthread_cond_signal(&cd.obj)
}
func (cd *Cond) broadcast(mu *Mutex) {
C.pthread_cond_broadcast(&cd.obj)
}

type Once struct {
Expand Down

0 comments on commit 703d101

Please sign in to comment.