Skip to content

GC-caused scheduler deadlock on RP2350 #5151

@herczegzsolt

Description

@herczegzsolt

Hi!

If I run the following simple code on an RP2350 board, it'll lock-up after only a few (2 or 3) cycles:

package main

import (
	"runtime"
	"machine"


	"time"
)

var (
	uart = machine.Serial
)

func main() {
	uart.Configure(machine.UARTConfig{})
	time.Sleep(1000 * time.Millisecond)
	uart.Write([]byte("\n Start"))
	for {
		uart.Write([]byte("\n Gosched: "))
		runtime.Gosched()
		uart.Write([]byte(" GC: "))
		runtime.GC()
		uart.Write([]byte("done"))
	}
}

The code freezes on the runtime.Gosched() line. By adding println statements to the tinygo standard library, I was able to see that the cause of the stop is that the runtime.schedulerLock mutex is already locked when Gosched() is called. I don't know if anything is happening on the other core, but this locked-up state never resolves itself.

The issue does not seem to happen, if I don't call runtime.GC() - so the lockup is somehow related.

I understand that there's no need to call runtime.GC() in a tight loop like that, but this is only a very simple reproducer of the issue that I've found while doing some memory-heavy math.

Switching the scheduler to none -scheduler=none does workaround the issue, but it means I cannot use any goroutines.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions