Skip to content

Multi-core scheduler for the RP2040 #4925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 13, 2025
Merged

Multi-core scheduler for the RP2040 #4925

merged 4 commits into from
Jun 13, 2025

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Jun 12, 2025

This PR depends on #4851. It needs to be rebased after that PR gets merged.

I've been testing it a bit with my badge code and it seems to be working well so far! It's unfortunately a bit more difficult to fully test than #4851, but I tried running a few tests in ./testdata and they seem to work correctly.

This PR also includes a few fixes for #4851, issues that I later realized and fixed in this PR as separate commits.

@deadprogram deadprogram modified the milestone: 0.38.0 Jun 12, 2025
Copy link

github-actions bot commented Jun 12, 2025

Size difference with the dev branch:

Binary size difference
 flash                          ram
 before   after   diff          before   after   diff
  61844   61844      0   0.00%    6180    6180      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go
   8840    8840      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go
  13572   13572      0   0.00%    6796    6796      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx
   9000    9000      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
  11816   11816      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go
   9264    9264      0   0.00%    4752    4752      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
   7576    7576      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
   8084    8084      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go
   7452    7452      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go
  71124   71124      0   0.00%    3656    3656      0   0.00% tinygo build -size short -o ./build/test.hex -target=pinetime     ./examples/bma42x/main.go
  64556   64556      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go
  27620   27620      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go
  64480   64480      0   0.00%    6220    6220      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go
  11944   11944      0   0.00%    4812    4812      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go
   7868    7868      0   0.00%    3352    3352      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go
  22184   22184      0   0.00%    3556    3556      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
  70136   70136      0   0.00%    6368    6368      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go
   4628    4628      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
  70328   70328      0   0.00%    6980    6980      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
  67088   67088      0   0.00%    9020    9020      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
   7300    7300      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
  67496   67496      0   0.00%    6360    6360      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go
  67912   67912      0   0.00%    6504    6504      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go
   7864    7864      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go
   5756    5756      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go
   5796    5796      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go
  10420   10420      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
  14700   14700      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
  16176   16176      0   0.00%    2364    2364      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
  10272   10272      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
  11060   11060      0   0.00%    4876    4876      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic
  29636   29636      0   0.00%   38076   38076      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing
  10300   10300      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll
  11140   11140      0   0.00%    4876    4876      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll
 263720  263720      0   0.00%   46744   46744      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow
  11044   11044      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
  14056   14056      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
  26348   26348      0   0.00%    2328    2328      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
  12368   12368      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
  10080   10080      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go
   9240    9240      0   0.00%    4772    4772      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go
   9644    9644      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go
   9488    9488      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go
  69220   69220      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go
  27148   27148      0   0.00%    3640    3640      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go
  26964   26964      0   0.00%    5620    5620      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go
   7540    7540      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go
   7448    7448      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go
  75832   75832      0   0.00%    7452    7452      0   0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
   6268    6268      0   0.00%    3292    3292      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
   4652    4652      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
   2841    2841      0   0.00%     558     558      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
   8216    8216      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
  58008   58008      0   0.00%    3688    3688      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
  58000   58000      0   0.00%    3696    3696      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
  58008   58008      0   0.00%    3688    3688      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
   6044    6044      0   0.00%    2288    2288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
   5572    5572      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
   5900    5900      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
   6808    6808      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
   6704    6704      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
  16784   16784      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go
  10124   10124      0   0.00%    4532    4532      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
  10180   10180      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
   9164    9164      0   0.00%    6780    6780      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
  12576   12576      0   0.00%    6976    6976      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
  15140   15140      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go
  13660   13660      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go
  24780   24780      0   0.00%   13720   13720      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go
   6532    6532      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
   6168    6168      0   0.00%    2316    2316      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
   6452    6452      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
   6960    6960      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
   5584    5584      0   0.00%    9538    9538      0   0.00% '-xesppie' is not a recognized feature for this target (ignoring feature)
  63216   63216      0   0.00%    5948    5948      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
   1581    1581      0   0.00%     598     598      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino   ./examples/ws2812
   1056    1056      0   0.00%     180     180      0   0.00% tinygo build -size short -o ./build/test.hex -target=digispark ./examples/ws2812
  32096   32096      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go
  16368   16368      0   0.00%    4724    4724      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/microphone/main.go
  11532   11532      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/buzzer/main.go
  12300   12300      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/veml6070/main.go
   6860    6860      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/simple/main.go
   8776    8776      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/speed/main.go
   6836    6836      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/simple/main.go
   9180    9180      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
   7416    7416      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go
   6732    6732      0   0.00%    2272    2272      0   0.00% '-xesppie' is not a recognized feature for this target (ignoring feature)
  13276   13276      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go
   9884    9884      0   0.00%    4764    4764      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go
  76656   76656      0   0.00%    6336    6336      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
  71748   71748      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
   7256    7256      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
  71292   71292      0   0.00%    6340    6340      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/
  71644   71644      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/
   8756    8756      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
  12344   12344      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina219/main.go
   9408    9408      0   0.00%    5248    5248      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
  74080   74080      0   0.00%   10756   10756      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
  62264   62264      0   0.00%    8228    8228      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
  10388   10388      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
  13220   13220      0   0.00%    4936    4936      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/
   8028    8028      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=circuitplay-express ./examples/makeybutton/main.go
   9572    9572      0   0.00%    4764    4764      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ds18b20/main.go
  82956   82956      0   0.00%    6592    6592      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/lora/lorawan/atcmd/
   7840    7840      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ttp229/main.go
  62588   62588      0   0.00%    3784    3784      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/main_ndir.go
  65592   65592      0   0.00%    6252    6252      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go
  12456   12456      0   0.00%    4544    4544      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=nicenano ./examples/sharpmem/main.go
  60768   60768      0   0.00%    5968    5968      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/max6675/main.go
 298544  298544      0   0.00%   15908   15908      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal -stack-size 8kb ./examples/net/http-get/
 119064  119064      0   0.00%    7828    7828      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size 8kb ./examples/net/tcpclient/
 102536  102536      0   0.00%    9808    9808      0   0.00% tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/
 339988  339988      0   0.00%   16520   16520      0   0.00% tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/
 111288  111288      0   0.00%    7784    7784      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/
 116284  116284      0   0.00%   13104   13104      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/
 290240  290240      0   0.00%   19564   19564      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/
 290544  290544      0   0.00%   20864   20864      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
 118012  118012      0   0.00%    9544    9544      0   0.00% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2350 -stack-size 8kb ./examples/net/ntpclient/
  30168   31776   1608   5.33%    3672    5732   2060  56.10% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/tmc2209/main.go
  36388   38040   1652   4.54%    3988    6048   2060  51.65% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8523/
  31208   32984   1776   5.69%    4544    6604   2060  45.33% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go
  10752   12540   1788  16.63%    3340    5404   2064  61.80% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive
  11980   13788   1808  15.09%    3324    5384   2060  61.97% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/uc8151/main.go
  11524   13332   1808  15.69%    3324    5388   2064  62.09% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
  10764   12584   1820  16.91%    3288    5352   2064  62.77% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/
   9256   11080   1824  19.71%    3288    5352   2064  62.77% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
   8280   10104   1824  22.03%    3760    5824   2064  54.89% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt
   9804   11632   1828  18.65%    3296    5360   2064  62.62% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu6886/main.go
  12192   14024   1832  15.03%    3352    5416   2064  61.58% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
  11156   12988   1832  16.42%    4252    6308   2056  48.35% tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go
  15968   17808   1840  11.52%    4956    7012   2056  41.49% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/as560x/main.go
   8896   10752   1856  20.86%    3276    5340   2064  63.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
  16564   18428   1864  11.25%    4172    6236   2064  49.47% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
  10400   12264   1864  17.92%    3356    5412   2056  61.26% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd4x/main.go
  67284   69196   1912   2.84%    4816    6888   2072  43.02% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ndir/main_ndir.go
  10480   12412   1932  18.44%    3328    5392   2064  62.02% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw
  13112   15044   1932  14.73%    3284    5348   2064  62.85% tinygo build -size short -o ./build/test.hex -target=pico ./examples/tmc5160/main.go
  13764   15700   1936  14.07%    3400    5464   2064  60.71% tinygo build -size short -o ./build/test.hex -target=pico     ./examples/sgp30
  25972   27908   1936   7.45%   16412   18476   2064  12.58% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go
  12112   14048   1936  15.98%    3304    5368   2064  62.47% tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go
  66644   68648   2004   3.01%    4784    6860   2076  43.39% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go
  86628   88776   2148   2.48%    5140    7260   2120  41.25% tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
 153776  155964   2188   1.42%    6524    8620   2096  32.13% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
 251032  253224   2192   0.87%   12860   15024   2164  16.83% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
 118132  120528   2396   2.03%    9504   11632   2128  22.39% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2040 -stack-size 8kb ./examples/net/tlsclient/
5703198 5754534  51336   0.02%  857222  913182  55960   0.08%

@aykevl
Copy link
Member Author

aykevl commented Jun 12, 2025

This PR does increase binary size for RP2040 chips (1½-2kB), but since they generally have plenty of flash memory I don't think that's a problem. And having multicore support by default seems more important to me.

@deadprogram
Copy link
Member

having multicore support by default seems more important to me.

💯 ❗

@deadprogram
Copy link
Member

Just tried this branch on an rp2040 app with 3 goroutines, one controlling display, another one running web server.

Worked perfectlyl!! Noticeably "snappier" than the single-core version. 😍

@deadprogram
Copy link
Member

I will rebase this as soon as the dev build is complete, to avoid any extra cache invalidation/LLVM rebuilds.

aykevl added 4 commits June 12, 2025 21:28
I forgot to add it in the first PR, here:
#4851
The GC shouldn't try to interrupt other cores before they are started.
For example, it would be possible for the GC to run in a package
initializer (which is currently run on a single core). That would
suggest questionable program design, but it is something that should
work. So this commit makes sure the GC only tries to scan the stack of
other cores when those other cores have in fact started.
This should avoid a deadlock when trying to print inside an interrupt,
if the interrupted code is also printing (and therefore has the print
lock taken).
@deadprogram
Copy link
Member

OK rebased.

@ysoldak
Copy link
Contributor

ysoldak commented Jun 12, 2025

Verified on XIAO-RP2040, works!
I can see my test code executes faster on this branch, compared to dev branch, so I assume it runs on two cores.

Test code

package main

import (
	"sync"
	"time"
	"math/rand"
)

func main() {

	time.Sleep(2 * time.Second)
	println(time.Now().Format("15:04:05.999999999"), "Starting goroutines")

	numbers := make(chan int, 100)

	wg := &sync.WaitGroup{}

	for i := 0; i < 2; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			v := 0
			for j := 0; j < 1000000; j++ {
				v += rand.Intn(100)
			}
			numbers <- v
		}()
	}

	wg.Wait()

	println(<-numbers)
	println(<-numbers)

	println(time.Now().Format("15:04:05.999999999"), "All goroutines finished")

}

Output on "dev" branch:

$ tinygo flash -target xiao-rp2040 -monitor ./src/examples/threads
Connected to /dev/cu.usbmodem101. Press Ctrl-C to exit.
00:00:02.007123 Starting goroutines
49519772
49530931
00:00:09.348277 All goroutines finished

Output on "threading-rp2040-3" branch:

$ tinygo flash -target xiao-rp2040 -monitor ./src/examples/threads
Connected to /dev/cu.usbmodem101. Press Ctrl-C to exit.
00:00:02.007233 Starting goroutines
49519204
49519305
00:00:06.583655 All goroutines finished

@ysoldak
Copy link
Contributor

ysoldak commented Jun 12, 2025

Sizes of the test code (see above).

On "dev" branch:

   code    data     bss |   flash     ram
  38608    1588    3272 |   40196    4860

On "threading-rp2040-3" branch:

   code    data     bss |   flash     ram
  40636    1580    5344 |   42216    6924

@deadprogram
Copy link
Member

https://github.com/tinygo-org/tinygo/blob/dev/main.go#L1545

Shouldn't cores be added to this list?

Side note: this PR also appears to still work as expected if you use -scheduler tasks with the previous behavior.

From reading of the code/datasheet, it appears that this will save power usage on the second core.

@aykevl
Copy link
Member Author

aykevl commented Jun 13, 2025

@deadprogram see #4927 for the outdated help text

@@ -43,6 +50,284 @@ func sleepTicks(d timeUnit) {
}
}

// Currently sleeping core, or 0xff.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ diff src/runtime/runtime_rp2*
1c1
< //go:build rp2040
---
> //go:build rp2350
31a32,35
>       if d <= 0 {
>               return
>       }
>

Can the two files be merged, unlocking multicore on rp2350 for (approximately) free?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, but I don't have a RP2350 to test. I think there are small differences that need to be accounted for.
I plan on getting a RP2350 soon!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will give you one next week!

Comment on lines +314 to +317
// TODO: use wfe and send an event when unlocking so the CPU can go to
// sleep while waiting for the lock.
// Unfortunately when doing that, time.Sleep() seems to hang somewhere.
// This needs some debugging to figure out.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could hide some other subtle error that affects not just time.Sleep. It seems risky to enable the multicore scheduler by default in v0.38.0 with so little bake time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"the voice of reason"? 😺

This should build with multicore I think:

tinygo flash -target=pico -scheduler=cores -ldflags="--defsym=__num_stacks=2" path/to/code

Perhaps we should consider it experimental for this release?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eliasnaur from reading the comment carefully, I interpret it to mean that the implementation in this PR could be improved by using wfe, but it does not yet due to the time.Sleep issue mentioned.

That does not change the point you are making overall. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another implication of changing the default to multicore, is that default power use will be higher with the second core active. ⚡

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think power consumption will be affected much: when one of the cores has nothing to do it will just go to sleep. But I didn't measure this. (Should be easy to do by compiling with -scheduler=tasks and -scheduler=cores and measuring the difference).

Copy link
Member Author

@aykevl aykevl Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the way it works (at least how I understand it), is that both cores are always running. The second core is just asleep on reset. With multicore support, it is pulled out of this sleep state and starts the scheduler - which in many cases will put it right back to sleep waiting for a goroutine to run. So yeah it spends a little time configuring stuff and then goes back to sleep.
...but again, I didn't measure anything so I'm only speculating how it should work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So yeah it spends a little time configuring stuff and then goes back to sleep.

That is what all of the docs and references I could find are claiming about power use. So it would appear to be fine as it is from that point of view.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could disable multicore support for now, and leave it for people who want to test it. It's possible there's a bug I didn't discover yet.

As much as this feature excites me, I think @eliasnaur is probably correct that we should not make it the default yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aykevl has a better idea of the robustness of the multi-core support than I; I merely pointed out the timing.

I'm also very excited about this code, and I would be comfortable making multi-core default, if the release notes spelled out instructions for switching back to the single-core scheduler. It's just a --scheduler=... argument, right? Assuming __num_stacks=2 is benign.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had already confirmed that -scheduler=tasks does what you would expect and runs on single core.

I assume that the extra stack space is wasted in that case, so I also tested this command (note I missed the extldflags in my original comment):

tinygo flash -target nano-rp2040 -ldflags="--extldflags '--defsym=__num_stacks=1'" -stack-size 8kb -scheduler tasks /path/to/my/code

This also worked correctly, and according to -size full did save some bytes.

Based on this, I think we can merge this PR as it is, and just add the docs to fallback to single core.

@deadprogram
Copy link
Member

Thank you very much for all your hard work on this amazing feature @aykevl and to everyone who helped review @ysoldak @eliasnaur others too.

Now merging!

@deadprogram deadprogram merged commit e238eb2 into dev Jun 13, 2025
29 of 30 checks passed
@deadprogram deadprogram deleted the threading-rp2040-3 branch June 13, 2025 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants