Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

Non-GC threads

Version 1
Created 2012-09-01
StatusDraft
Last modified 2012-09-01
Author Piotr Szturmaj

Abstract

The proposal is to create a base for safe, non garbage-collected threads. This is done by adding nogc attribute for functions. nogc functions cannot perform operations that may allocate garbage collected memory. They are covariant with gc ones.

Rationale

Currently, all functions can use garbage collected memory. Threads that call those functions must be managed by the garbage collector, which may occasionally suspend them to perform collection. This can lead to unwanted pauses, that are not acceptable in some situations, mainly real-time audio/video processing, gaming, and others. Rather than relying on particular (concurrent) implementation of the GC, or resorting to unsafe solutions, a language-level guarantee is proposed. Guarantee is that threads that spawn nogc functions will not be suspended during their execution.

It’s possible to create non-gc threads now, but current practices are unsafe and error prone. For example, one must check the code of all called functions to see if they don’t perform GC allocations. In this proposal, compiler guarantees that functions don’t allocate GC memory. This is similar to nothrow and pure handling. Compiler guarantees that pure functions can’t call impure ones, and nothrow functions can’t call throwing ones.

Description

Functions can be marked with nogc attribute, similarly to nothrow or pure marking. Nogc functions can’t perform operations listed here (D Operations That Involve the Garbage Collector). That is, they can’t do:

   void func() nogc    {        auto ptr = malloc(4096); // ok        auto instance = new SomeClass(); // Error: nogc functions can't allocate using new    }

Nogc functions are statically checked by the compiler. If at least one of the operations listed above is used, this results in a compilation error.

Functions not marked with nogc attribute are called “gc” functions. All gc functions can call nongc functions, but nongc functions can’t call gc ones. This is analogous to pure and nothrow behavior. Compiler should infer nogc attribute automatically for matching functions, while explicit nogc attribute will force non-gc check on programmer’s demand.

Nogc functions are handled differently when they’re used to spawn threads:

Newly created thread is not added to the GC’s thread list. This way it’s never suspended. If some of the function’s arguments take references (directly or indirectly), then all of them are automatically added to the list of GC roots (addRoot()). It is possible to mark entry-point functions with nogc:

   void main() nogc    {    }

This way entire program is guaranteed to not use GC at all (given that no static module constructors use GC). Code of the garbage collector doesn’t need to be linked, leading to smaller executables. This is also useful for writing programs that run in constrained environments, for example kernel-mode drivers or embedded/microcontroller software.

After all, users can benefit from proper modules, templates, clean syntax and other nice features of D, without using garbage collector.

This document has been placed in the Public Domain.