Skip to content
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

Implement race-free signals using futexes #4586

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open

Implement race-free signals using futexes #4586

wants to merge 2 commits into from

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Nov 7, 2024

Use a futex instead of the previous rather complicated code with signal masking. It was race free (I hope!) on Linux but not on MacOS. This PR makes it race-free on MacOS too.

Sleeping is very simple: just use a futex with a timeout and if the futex value changed we know there was a signal. There shouldn't be any race conditions with this approach.

This also adds an internal/futex package which I intend to reuse in #4559.

Copy link

github-actions bot commented Nov 7, 2024

Size difference with the dev branch:

Binary size difference
not the same command!
    tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
    go: downloading tinygo.org/x/tinyfont v0.3.0
not the same command!
    tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
    go: downloading golang.org/x/net v0.7.0
not the same command!
    tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
    go: downloading github.com/soypat/natiu-mqtt v0.5.1
not the same command!
    tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
    go: downloading github.com/eclipse/paho.mqtt.golang v1.2.0
 flash                          ram
 before   after   diff          before   after   diff
  16864   16864      0   0.00%    4324    4324      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
  61432   61432      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go
   9568    9568      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go
  13564   13564      0   0.00%    6796    6796      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx
   8680    8680      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
  11800   11800      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
   9796    9796      0   0.00%    4768    4768      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
   8368    8368      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
   8124    8124      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go
   7432    7432      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go
  70576   70576      0   0.00%    3660    3660      0   0.00% tinygo build -size short -o ./build/test.hex -target=pinetime     ./examples/bma42x/main.go
  63956   63956      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go
  27412   27412      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go
  64008   64008      0   0.00%    6228    6228      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go
  12200   12200      0   0.00%    4820    4820      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go
   8180    8180      0   0.00%    3348    3348      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go
  22168   22168      0   0.00%    3544    3544      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
  69712   69712      0   0.00%    6376    6376      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go
   4620    4620      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
  69256   69256      0   0.00%    6976    6976      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
  65588   65588      0   0.00%    9012    9012      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
   7212    7212      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
  67580   67580      0   0.00%    6368    6368      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go
  68108   68108      0   0.00%    6504    6504      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go
   7872    7872      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go
   5832    5832      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go
   5784    5784      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go
  10528   10528      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
  14724   14724      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
  16148   16148      0   0.00%    2360    2360      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
  10152   10152      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
  10644   10644      0   0.00%    4868    4868      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic
  29504   29504      0   0.00%   38076   38076      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing
  10172   10172      0   0.00%    6924    6924      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll
  10732   10732      0   0.00%    4876    4876      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll
 263660  263660      0   0.00%   46760   46760      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow
  11732   11732      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
  14068   14068      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
  26132   26132      0   0.00%    2328    2328      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
  12448   12448      0   0.00%    4796    4796      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
  10744   10744      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go
   9916    9916      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go
  10368   10368      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go
   9780    9780      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go
  68600   68600      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go
  27260   27260      0   0.00%    3648    3648      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go
  26972   26972      0   0.00%    5696    5696      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go
   8240    8240      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go
   8148    8148      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go
  75856   75856      0   0.00%    7480    7480      0   0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
  12252   12252      0   0.00%    3352    3352      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
   6228    6228      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
   5260    5260      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
  10536   10536      0   0.00%    3328    3328      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw
   2825    2825      0   0.00%     558     558      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
  13768   13768      0   0.00%    3400    3400      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico     ./examples/sgp30
   8080    8080      0   0.00%    6796    6796      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
  57412   57412      0   0.00%    3692    3692      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
  57468   57468      0   0.00%    3700    3700      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
  57376   57376      0   0.00%    3692    3692      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
   6688    6688      0   0.00%    2288    2288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
   6140    6140      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
   5844    5844      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
   6784    6784      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
   6696    6696      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
  16964   16964      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go
  10520   10520      0   0.00%    4540    4540      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
  10068   10068      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
  10868   10868      0   0.00%    3340    3340      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive
   9520    9520      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
  12588   12588      0   0.00%    6984    6984      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
  14980   14980      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go
  13460   13460      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go
  24700   24700      0   0.00%   13892   13892      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go
   6488    6488      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
   6176    6176      0   0.00%    2312    2312      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
   6400    6400      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
  26452   26452      0   0.00%   16732   16732      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go
   6848    6848      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
   5764    5764      0   0.00%    9538    9538      0   0.00% tinygo build -size short -o ./build/test.bin -target=m5stamp-c3          ./examples/ws2812
  62444   62444      0   0.00%    5952    5952      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
  31856   31856      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go
  16436   16436      0   0.00%    4732    4732      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/microphone/main.go
  11080   11080      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/buzzer/main.go
  12788   12788      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/veml6070/main.go
   6752    6752      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/simple/main.go
   8664    8664      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/speed/main.go
   6720    6720      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/simple/main.go
   9276    9276      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
   7336    7336      0   0.00%    3320    3320      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go
   7012    7012      0   0.00%    2268    2268      0   0.00% tinygo build -size short -o ./build/test.hex -target=hifive1b ./examples/ssd1351/main.go
  13004   13004      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go
   8880    8880      0   0.00%    4764    4764      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go
  77292   77292      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
  36532   36532      0   0.00%    3988    3988      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8523/
  71320   71320      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
   7276    7276      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
  70848   70848      0   0.00%    6340    6340      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/
  71280   71280      0   0.00%    6352    6352      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/
  12184   12184      0   0.00%    3304    3304      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go
  10808   10808      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/
   8744    8744      0   0.00%    4756    4756      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
  13196   13196      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina219/main.go
   9328    9328      0   0.00%    5260    5260      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
  72676   72676      0   0.00%   10748   10748      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
  61544   61544      0   0.00%    8232    8232      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
  10296   10296      0   0.00%    6796    6796      0   0.00% tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
   9028    9028      0   0.00%    3276    3276      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
  13748   13748      0   0.00%    4940    4940      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/
  31352   31352      0   0.00%    4548    4548      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go
  11256   11256      0   0.00%    4252    4252      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go
  11952   11952      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/uc8151/main.go
  10428   10428      0   0.00%    3356    3356      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd4x/main.go
   8552    8552      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=circuitplay-express ./examples/makeybutton/main.go
   9664    9664      0   0.00%    4772    4772      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ds18b20/main.go
  83184   83184      0   0.00%    6588    6588      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/lora/lorawan/atcmd/
  15916   15916      0   0.00%    4880    4880      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/as560x/main.go
   9888    9888      0   0.00%    3296    3296      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu6886/main.go
   7808    7808      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ttp229/main.go
  66848   66848      0   0.00%    4816    4816      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ndir/main_ndir.go
  62300   62300      0   0.00%    3788    3788      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/main_ndir.go
  65284   65284      0   0.00%    6260    6260      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go
   9316    9316      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
  11396   11396      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
   8456    8456      0   0.00%    3760    3760      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt
  65816   65816      0   0.00%    4784    4784      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go
  85924   85924      0   0.00%    5140    5140      0   0.00% tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
 296644  296644      0   0.00%   13788   13788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal -stack-size 8kb ./examples/net/http-get/
 119376  119376      0   0.00%    7848    7848      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size 8kb ./examples/net/tcpclient/
 245516  245516      0   0.00%   10488   10488      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
 103112  103112      0   0.00%    9816    9816      0   0.00% tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/
 338452  338452      0   0.00%   15396   15396      0   0.00% tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/
 111588  111588      0   0.00%    7772    7772      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/
 154216  154216      0   0.00%    6540    6540      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
 117048  117048      0   0.00%   13132   13132      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/
 286136  286136      0   0.00%   17812   17812      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/
 287132  287132      0   0.00%   18212   18212      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
5332918 5332918      0   0.00%  811790  811790      0   0.00%

@aykevl aykevl marked this pull request as ready for review November 7, 2024 14:45
@aykevl aykevl force-pushed the signal-races branch 3 times, most recently from 7d64d51 to 7a88512 Compare November 7, 2024 15:31
Copy link
Contributor

@eliasnaur eliasnaur left a comment

Choose a reason for hiding this comment

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

Nice improvement. A few comments from the peanut gallery.

Comment on lines +12 to +14
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_PRIVATE_FLAG 128
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not #include <linux/futex.h>?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because this header file is not available in musl, which we use.

Comment on lines +8 to +14
int __ulock_wait(uint32_t operation, void *addr, uint64_t value, uint32_t timeout_us);
int __ulock_wait2(uint32_t operation, void *addr, uint64_t value, uint64_t timeout_ns, uint64_t value2);
int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value);
Copy link
Contributor

Choose a reason for hiding this comment

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

Link to documentation, if it exists somewhere (semi-)stable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. There's no real documentation, but someone has figured out these calls: https://outerproduct.net/futex-dictionary.html

// to sleep. Return true if we were definitely awoken by a call to Wake or
// WakeAll, and false if we can't be sure of that.
func (f *Futex) Wait(cmp uint32) bool {
tinygo_futex_wait((*uint32)(unsafe.Pointer(&f.Uint32)), cmp)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's probably ok to assume the layout of atomic.Uint32 here and below, but it seems to me you can avoid it by

type Futex struct {
    v uint32
}

and adding methods that forwards to atomic.(Load|And|Store...)Uint32 functions.

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'd prefer to keep using atomic.Uint32. I don't expect atomic.Uint32 to ever change to something else, and if it does we can always update this code.


// Like Wait, but times out after the number of nanoseconds in timeout.
// If timeout is 0, it may or may not be treated as Wait with infinite timeout.
// Therefore, make sure the timeout value is non-zero.
Copy link
Contributor

Choose a reason for hiding this comment

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

Given #4568 et al can a zero timeout be tightened to always do the least surprising thing, even if it means timeout = max(timeout, 1) here or in the platform implementations?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. I don't see a way this can happen currently (the two places that call sleepTicks make sure it's called with a positive timeout) but since this is MacOS and not some constrainted microcontroller it doesn't really hurt to put in an extra check.

Comment on lines +24 to +39
// Note: __ulock_wait2 is available since MacOS 11.
// I think that's fine, since the version before that (MacOS 10.15) is EOL
// since 2022. Though if needed, we could certainly use __ulock_wait instead
// and deal with the smaller timeout value.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I would put (most of) this note in the commit message. Go 1.23 also requires macOS 11 and it doesn't seem reasonable to do better in TinyGo.

Comment on lines 228 to 229
if !hasScheduler {
until = ticks() + d
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why this code depends on hasScheduler.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that's a bug. Thanks for spotting it! (I probably modified the code a few times and it probably made sense to not calculate until without a scheduler before).
I'll push a fix.

Comment on lines +246 to +249
// Set duration (in next loop iteration) to the remaining time.
d = until - ticks()
if d <= 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

If hasScheduler, d will always be less than zero, no?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not necessarily! There are cases where Wait and WaitUntil might return due to spurious wakeups and not due to a signal. I'm not entirely sure whether this is possible, but the futex documentation on Linux is a bit vague on it (see src/internal/futex/futex.go) and since there's no real documentation for the MacOS syscalls I think it's better to defensively assume they can return spuriously. (I know that on Windows, the equivalent syscalls do return spuriously sometimes).

@dgryski
Copy link
Member

dgryski commented Nov 19, 2024

Can you rebase so we get the fix for the wasm failure hitting the linux-assert build?

This really is the only sane way to register a signal. If this flag is
not set, many syscalls will return EINTR (and not complete their
operation) which will be a massive source of hard-to-debug bugs.
This requires an API introduced in MacOS 11. I think that's fine, since
the version before that (MacOS 10.15) is EOL since 2022. Though if
needed, we could certainly work around it by using an older and slightly
less nice API.
@aykevl
Copy link
Member Author

aykevl commented Nov 19, 2024

Rebased!

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.

3 participants