runtime: testing runtime

This commit is contained in:
Li Jie
2025-02-14 17:18:13 +08:00
parent 66909b3000
commit 5329f28580
83 changed files with 3376 additions and 2061 deletions

View File

@@ -4,23 +4,27 @@
package time
import (
"sync"
"unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/libuv"
)
// Sleep pauses the current goroutine for at least the duration d.
// A negative or zero duration causes Sleep to return immediately.
func Sleep(d Duration) {
panic("todo: time.Sleep")
c.Usleep(c.Uint(d.Nanoseconds()))
}
// Interface to timers implemented in package runtime.
// Must be in sync with ../runtime/time.go:/^type timer
type runtimeTimer struct {
pp uintptr
when int64
period int64
f func(any, uintptr) // NOTE: must not be closure
arg any
seq uintptr
nextwhen int64
status uint32
libuv.Timer
when int64
f func(any, uintptr)
arg any
}
// when is a helper function for setting the 'when' field of a runtimeTimer.
@@ -40,10 +44,6 @@ func when(d Duration) int64 {
return t
}
func startTimer(*runtimeTimer) { panic("todo: time.startTimer") }
func stopTimer(*runtimeTimer) bool { panic("todo: time.stopTimer") }
func resetTimer(*runtimeTimer, int64) bool { panic("todo: time.resetTimer") }
/* TODO(xsw):
func modTimer(t *runtimeTimer, when, period int64, f func(any, uintptr), arg any, seq uintptr) {
panic("todo: time.modTimer")
@@ -82,9 +82,6 @@ type Timer struct {
// If the caller needs to know whether f is completed, it must coordinate
// with f explicitly.
func (t *Timer) Stop() bool {
if t.r.f == nil {
panic("time: Stop called on uninitialized Timer")
}
return stopTimer(&t.r)
}
@@ -139,9 +136,6 @@ func NewTimer(d Duration) *Timer {
// one. If the caller needs to know whether the prior execution of
// f is completed, it must coordinate with f explicitly.
func (t *Timer) Reset(d Duration) bool {
if t.r.f == nil {
panic("time: Reset called on uninitialized Timer")
}
w := when(d)
return resetTimer(&t.r, w)
}
@@ -182,3 +176,64 @@ func AfterFunc(d Duration, f func()) *Timer {
func goFunc(arg any, seq uintptr) {
go arg.(func())()
}
var (
timerLoop *libuv.Loop
timerOnce sync.Once
)
func init() {
timerOnce.Do(func() {
timerLoop = libuv.LoopNew()
})
go func() {
timerLoop.Run(libuv.RUN_DEFAULT)
}()
}
// cross thread
func timerEvent(async *libuv.Async) {
a := (*asyncTimerEvent)(unsafe.Pointer(async))
a.cb()
a.Close(nil)
}
type asyncTimerEvent struct {
libuv.Async
cb func()
}
func timerCallback(t *libuv.Timer) {
}
func startTimer(r *runtimeTimer) {
asyncTimer := &asyncTimerEvent{
cb: func() {
libuv.InitTimer(timerLoop, &r.Timer)
r.Start(timerCallback, uint64(r.when), 0)
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
asyncTimer.Send()
}
func stopTimer(r *runtimeTimer) bool {
asyncTimer := &asyncTimerEvent{
cb: func() {
r.Stop()
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
return asyncTimer.Send() == 0
}
func resetTimer(r *runtimeTimer, when int64) bool {
asyncTimer := &asyncTimerEvent{
cb: func() {
r.Stop()
r.Start(timerCallback, uint64(when), 0)
},
}
timerLoop.Async(&asyncTimer.Async, timerEvent)
return asyncTimer.Send() == 0
}

View File

@@ -0,0 +1,36 @@
package time
import "unsafe"
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
}
func NewTicker(d Duration) *Ticker {
if d <= 0 {
panic("non-positive interval for NewTicker")
}
c := make(chan Time, 1)
t := &Timer{C: c}
t.C = c
startTimer(&t.r)
return (*Ticker)(unsafe.Pointer(t))
}
func (t *Ticker) Stop() {
stopTimer(&(*Timer)(unsafe.Pointer(t)).r)
}
func (t *Ticker) Reset(d Duration) {
if d <= 0 {
panic("non-positive interval for Ticker.Reset")
}
resetTimer(&(*Timer)(unsafe.Pointer(t)).r, when(d))
}
func Tick(d Duration) <-chan Time {
if d <= 0 {
return nil
}
return NewTicker(d).C
}

View File

@@ -187,6 +187,10 @@ func (t Time) Compare(u Time) int {
return 0
}
func (t Time) UnixNano() int64 {
return (t.unixSec())*1e9 + int64(t.nsec())
}
// Equal reports whether t and u represent the same time instant.
// Two times can be equal even if they are in different locations.
// For example, 6:00 +0200 and 4:00 UTC are Equal.