Skip to content

Instantly share code, notes, and snippets.

@RickCarlino
Created August 23, 2020 03:12
Show Gist options
  • Save RickCarlino/7905576869c3fda95385483880548262 to your computer and use it in GitHub Desktop.
Save RickCarlino/7905576869c3fda95385483880548262 to your computer and use it in GitHub Desktop.
Multitask in RetroForth

Multitasking in Retro

This is a beta feature. For early access, consider donating to the RetroForth Patreon.

High Level Overview

Retro exposes multitasking as an I/O device at the VM layer.

#900 'task:DEVICE_ID const

The I/O device exposes 5 syscalls.

#0 'task:SYSCALL_ADD
#1 'task:SYSCALL_SET_CYCLES
#2 'task:SYSCALL_YIELD
#3 'task:SYSCALL_KILL
#4 'task:SYSCALL_TASK_ID

Invoking mt Syscalls

Since not all VMs support multitasking, you may wish to perform a preflight check prior to invoking multitasking syscalls.

{{

  :mt-disabled! drop 'IO_DEVICE_TYPE_0900_NOT_FOUND s:put nl ;

  :mt-enabled? task:DEVICE_ID io:scan-for dup n:negative? ;

  :no-tasks @Tasks n:zero? ;

  :safe-!Tasks mt-enabled? [ mt-disabled! ] [ !Tasks ] choose ;

  'Tasks var

  :identify no-tasks? &safe-!Tasks if ;

---reveal---

  :io:mt-syscall identify @Tasks io:invoke ;

}}

Syscall Helpers

Adding a New Task

A maximum of 64 tasks may be added.

:task:add        (a-n) task:SYSCALL_ADD        io:mt-syscall ;

Setting Cycle Count

Tasks receive a finite number of execution cycles in a round-robin. This number can be changed at runtime.

:task:set-cycles (n-)  task:SYSCALL_SET_CYCLES io:mt-syscall ;

"Finishing Early"

A task may voluntarily forfeit its remaining cycles.

:task:yield      (-)   task:SYSCALL_YIELD      io:mt-syscall ;

Killing a Task

:task:kill       (n-)  task:SYSCALL_KILL       io:mt-syscall ;

Determining the Current Task's ID

:task:id         (-n)  task:SYSCALL_TASK_ID    io:mt-syscall ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment