1 Overview (CS)
The Racket CS runtime system is implemented by a wrapper around the Chez Scheme kernel. The wrapper implements additional glue to the operating system (e.g., for I/O and networking) and provides entry points into the Racket layer’s evaluator.
1.1 “S” versus “Racket”
In the C API for Racket CS, names that start with S are from the Chez Scheme layer, while names that start with racket_ are from the Racket wrapper.
1.2 Racket CS Memory Management
Racket values may be moved or garbage collected any time that racket_... functions are used to run Racket code. Do not retain a reference to any Racket value across such a call. This requirement contrasts with the BC implementation of Racket, which provides a way for C code to more directly cooperate with the memory manager.
API functions that start with S do not collect or move objects unless noted otherwise, so references to Racket values across such calls is safe.
The Slock_object function can prevent an object from being moved or garbage collected, but it should be used sparingly. Garbage collection can be disabled entirely by calling the Chez Scheme function disable-interrupts, and then reenabled with a balancing call to enable-interrupts; access those functions via racket_primitive and call them via Scall0. Beware that disabling interrupts also disables context switching for Racket threads and signal handling for breaks. Assuming that interrupts start out enabled, calling disable-interrupts could trigger a garbage collection before further collections are disabled.
1.3 Racket CS and Places
Each Racket place corresponds to a Chez Scheme thread, which also corresponds to an OS-implemented thread. Chez Scheme threads share a global allocation space, so GC-managed objects can be safely be communicated from one place to another. Beware, however, that Chez Scheme threads are unsafe; any synchronization needed to safely share a value across places is must be implemented explicitly. Racket-level functions for places will only share values across places when they can be safely used in both places.
In an embedding application, the OS thread that originally calls racket_boot is the OS thread of the original place.
1.4 Racket CS and Threads
Racket implements threads for Racket programs without aid from the operating system or Chez Scheme’s threads, so that Racket threads are cooperative from the perspective of C code. Stand-alone Racket uses a few private OS-implemented threads for background tasks, but these OS-implemented threads are never exposed by the Racket API.
Racket can co-exist with additional OS-implemented threads, but care must be taken when calling S functions, and additional OS or Chez Scheme threads must not call any racket_ function. For other OS threads to call S functions, the thread must be first activated as a Chez Scheme thread using Sactivate_thread.
1.5 Racket CS Integers
The C type iptr is defined by Racket CS headers to be an integer type that is big enough to hold a pointer value. In other words, it is an alias for intptr_t. The uptr type is the unsigned variant.