diff --git a/runtime/internal/lib/runtime/nanotime_darwin_llgo.go b/runtime/internal/lib/runtime/nanotime_darwin_llgo.go new file mode 100644 index 0000000000..7d487edadf --- /dev/null +++ b/runtime/internal/lib/runtime/nanotime_darwin_llgo.go @@ -0,0 +1,36 @@ +//go:build darwin && !baremetal + +/* + * Copyright (c) 2026 The XGo Authors (xgo.dev). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + _ "unsafe" +) + +// Mirrors Go's runtime.nanotime1 on Darwin (sys_darwin.go): read +// CLOCK_UPTIME_RAW through clock_gettime_nsec_np. Darwin serves +// clock_gettime(CLOCK_MONOTONIC) with only microsecond granularity, while +// CLOCK_UPTIME_RAW is mach_absolute_time with full nanosecond resolution. +const _CLOCK_UPTIME_RAW = 8 + +//go:linkname c_clock_gettime_nsec_np C.clock_gettime_nsec_np +func c_clock_gettime_nsec_np(clockID int32) uint64 + +func nanotime1() int64 { + return int64(c_clock_gettime_nsec_np(_CLOCK_UPTIME_RAW)) +} diff --git a/runtime/internal/lib/runtime/nanotime_linux_llgo.go b/runtime/internal/lib/runtime/nanotime_linux_llgo.go new file mode 100644 index 0000000000..a07def21eb --- /dev/null +++ b/runtime/internal/lib/runtime/nanotime_linux_llgo.go @@ -0,0 +1,40 @@ +//go:build linux && !baremetal + +/* + * Copyright (c) 2026 The XGo Authors (xgo.dev). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + ct "github.com/goplus/llgo/runtime/internal/clite/time" +) + +// Linux CLOCK_MONOTONIC (see ), which has nanosecond +// resolution. Deliberately a local constant: ct.CLOCK_MONOTONIC carries +// Darwin's id (6), which Linux interprets as CLOCK_MONOTONIC_COARSE — a +// millisecond-granularity clock that quantized every monotonic timestamp +// the runtime produced. +const _CLOCK_MONOTONIC = 1 + +// nanotime1 mirrors Go's runtime.nanotime1 on Linux. +func nanotime1() int64 { + tv := (*ct.Timespec)(c.Alloca(unsafe.Sizeof(ct.Timespec{}))) + ct.ClockGettime(ct.ClockidT(_CLOCK_MONOTONIC), tv) + return int64(tv.Sec)*1e9 + int64(tv.Nsec) +} diff --git a/runtime/internal/lib/runtime/nanotime_llgo.go b/runtime/internal/lib/runtime/nanotime_llgo.go new file mode 100644 index 0000000000..d9644d6281 --- /dev/null +++ b/runtime/internal/lib/runtime/nanotime_llgo.go @@ -0,0 +1,25 @@ +//go:build !baremetal + +/* + * Copyright (c) 2026 The XGo Authors (xgo.dev). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +// runtimeNano mirrors Go's runtime.nanotime: the monotonic clock in +// nanoseconds, implemented per OS by nanotime1. +func runtimeNano() int64 { + return nanotime1() +} diff --git a/runtime/internal/lib/runtime/nanotime_other_llgo.go b/runtime/internal/lib/runtime/nanotime_other_llgo.go new file mode 100644 index 0000000000..8478b3ec8f --- /dev/null +++ b/runtime/internal/lib/runtime/nanotime_other_llgo.go @@ -0,0 +1,33 @@ +//go:build !darwin && !linux && !baremetal + +/* + * Copyright (c) 2026 The XGo Authors (xgo.dev). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + ct "github.com/goplus/llgo/runtime/internal/clite/time" +) + +// nanotime1 keeps the previous behavior on remaining platforms. +func nanotime1() int64 { + tv := (*ct.Timespec)(c.Alloca(unsafe.Sizeof(ct.Timespec{}))) + ct.ClockGettime(ct.CLOCK_MONOTONIC, tv) + return int64(tv.Sec)*1e9 + int64(tv.Nsec) +} diff --git a/runtime/internal/lib/runtime/time_llgo.go b/runtime/internal/lib/runtime/time_llgo.go index 0a09c98e07..bc4586dd77 100644 --- a/runtime/internal/lib/runtime/time_llgo.go +++ b/runtime/internal/lib/runtime/time_llgo.go @@ -545,9 +545,3 @@ func timeSleepWake(arg any, _ uintptr) { ch := arg.(chan struct{}) ch <- struct{}{} } - -func runtimeNano() int64 { - tv := (*ct.Timespec)(c.Alloca(unsafe.Sizeof(ct.Timespec{}))) - ct.ClockGettime(ct.CLOCK_MONOTONIC, tv) - return int64(tv.Sec)*1e9 + int64(tv.Nsec) -} diff --git a/runtime/internal/lib/runtime/time_llgo_go123.go b/runtime/internal/lib/runtime/time_llgo_go123.go index ceb2d73ed4..85661dd122 100644 --- a/runtime/internal/lib/runtime/time_llgo_go123.go +++ b/runtime/internal/lib/runtime/time_llgo_go123.go @@ -579,9 +579,3 @@ func resetTimer(t *timeTimer, when, period int64) bool { r := &t.r return resetRuntimeTimer(r, when, period, r.f, r.arg, r.seq) } - -func runtimeNano() int64 { - tv := (*ct.Timespec)(c.Alloca(unsafe.Sizeof(ct.Timespec{}))) - ct.ClockGettime(ct.CLOCK_MONOTONIC, tv) - return int64(tv.Sec)*1e9 + int64(tv.Nsec) -}