mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 11:37:46 +00:00
743bf45e00
Make timeoffset atomic to be able to handle changing the system time. Otherwise the scheduler can gets rather confused if you call AdjustTimeOffset when there are multiple goroutines already running. Signed-off-by: deadprogram <ron@hybridgroup.com>
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
//go:build baremetal
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"unsafe"
|
|
)
|
|
|
|
//go:extern _heap_start
|
|
var heapStartSymbol [0]byte
|
|
|
|
//go:extern _heap_end
|
|
var heapEndSymbol [0]byte
|
|
|
|
//go:extern _globals_start
|
|
var globalsStartSymbol [0]byte
|
|
|
|
//go:extern _globals_end
|
|
var globalsEndSymbol [0]byte
|
|
|
|
//go:extern _stack_top
|
|
var stackTopSymbol [0]byte
|
|
|
|
var (
|
|
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
|
heapEnd = uintptr(unsafe.Pointer(&heapEndSymbol))
|
|
globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
|
|
globalsEnd = uintptr(unsafe.Pointer(&globalsEndSymbol))
|
|
stackTop = uintptr(unsafe.Pointer(&stackTopSymbol))
|
|
)
|
|
|
|
// growHeap tries to grow the heap size. It returns true if it succeeds, false
|
|
// otherwise.
|
|
func growHeap() bool {
|
|
// On baremetal, there is no way the heap can be grown.
|
|
return false
|
|
}
|
|
|
|
//export malloc
|
|
func libc_malloc(size uintptr) unsafe.Pointer {
|
|
// Note: this zeroes the returned buffer which is not necessary.
|
|
// The same goes for bytealg.MakeNoZero.
|
|
return alloc(size, nil)
|
|
}
|
|
|
|
//export calloc
|
|
func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
|
|
// No difference between calloc and malloc.
|
|
return libc_malloc(nmemb * size)
|
|
}
|
|
|
|
//export free
|
|
func libc_free(ptr unsafe.Pointer) {
|
|
free(ptr)
|
|
}
|
|
|
|
//export runtime_putchar
|
|
func runtime_putchar(c byte) {
|
|
putchar(c)
|
|
}
|
|
|
|
//go:linkname syscall_Exit syscall.Exit
|
|
func syscall_Exit(code int) {
|
|
exit(code)
|
|
}
|
|
|
|
const baremetal = true
|
|
|
|
// timeOffset is how long the monotonic clock started after the Unix epoch. It
|
|
// should be a positive integer under normal operation or zero when it has not
|
|
// been set.
|
|
var timeOffset atomic.Int64
|
|
|
|
//go:linkname now time.now
|
|
func now() (sec int64, nsec int32, mono int64) {
|
|
mono = nanotime()
|
|
to := timeOffset.Load()
|
|
sec = (mono + to) / (1000 * 1000 * 1000)
|
|
nsec = int32((mono + to) - sec*(1000*1000*1000))
|
|
return
|
|
}
|
|
|
|
// AdjustTimeOffset adds the given offset to the built-in time offset. A
|
|
// positive value adds to the time (skipping some time), a negative value moves
|
|
// the clock into the past.
|
|
func AdjustTimeOffset(offset int64) {
|
|
timeOffset.Add(offset)
|
|
}
|
|
|
|
// Picolibc is not configured to define its own errno value, instead it calls
|
|
// __errno_location.
|
|
// TODO: a global works well enough for now (same as errno on Linux with
|
|
// -scheduler=tasks), but this should ideally be a thread-local variable stored
|
|
// in task.Task.
|
|
// Especially when we add multicore support for microcontrollers.
|
|
var errno int32
|
|
|
|
//export __errno_location
|
|
func libc_errno_location() *int32 {
|
|
return &errno
|
|
}
|