Thread overview
LWDR (Light Weight D Runtime) v0.3.0
Jun 19, 2021
Dylan Graham
Jun 19, 2021
Dylan Graham
Jul 09, 2021
Jul 09, 2021
rikki cattermole
Jul 09, 2021
Dylan Graham
June 19, 2021

Previous announcement

LWDR (Light Weight D Runtime) is a ground-up implementation of a D runtime targeting the ARM Cortex-M microcontrollers and other barebones environments. It works by providing a series of basic API hooks (as defined in rtoslink.d that you must implement and/or point to your RTOS implementation.

This is V0.3.0 of LWDR. Since V0.2.3, the following has been worked on:

  1. Thread Local Storage support
  2. Primitive memory tracking for Phobos allocations that would normally rely on a GC
  3. Transition to an opt-in system
  4. Replacement of delete with due to deprecation
  5. Source code documentation improvements
  6. RefCount!T and Unique!T LWDR-specific implementations

Thread Local Storage
This feature is rather abstract, and it is an opt-in with version LWDR_TLS. You must provide support in your linker script for tdata and tbss sections. It works by utilising the underlying RTOS's TLS implementation (example). When LWDR.registerCurrentThread() is called a block of D memory is allocated containing the TLS variables for the current thread, and the pointer to the block is stored in the thread's TCB (Thread Control Block). When a TLS variable (ie, a static variable) is accessed, __aeabi_read_tp is called, yielding the pointer.

Memory Tracking
This is very primitive. It's only meant to assist with stopping GC-reliant stdlib allocations from leaking. It pretty much behaves as defined here.

Opt In
To be able to keep the size of TypeInfo vtables down and such, LWDR has adopted an opt-in system, which relies on D's version feature. The current opt-ins are:

  1. LWDR_TLS - Enables TLS support
  2. LWDR_DynamicArray - Enables dynamic arrays
  3. LWDR_TrackMem - Enables the mess above.

Replacement of delete
delete has been deprecated. has been implemented in its place to prevent compiler warnings.

Source Code Documentation
Runtimes are hairy and scary - so I'm beginning to put more effort into documenting how things work. So far, it's only ddoc comments.

RefCount!T and Unique!T
To alleviate the lack of GC, I have implemented an LWDR-specific solution inspired by automem.

What works?

  1. Class allocations and deallocations (via new and
  2. Struct heap allocations and deallocations (via new and
  3. Invariants
  4. Asserts
  5. Contract programming
  6. Basic RTTI (via TypeInfo stubs)
  7. Interfaces
  8. Static Arrays
  9. Virtual functions and overrides
  10. Abstract classes
  11. Static classes
  12. Allocation and deallocation of dynamic arrays (opt in by version LWDR_DynamicArray)
  13. Concatenate an item to a dynamic array (opt in by version LWDR_DynamicArray)
  14. Concatenate two dynamic arrays together (opt in by version LWDR_DynamicArray)
  15. Dynamic array resizing (opt in by version LWDR_DynamicArray)
  16. Thread local storage (opt in by version LWDR_TLS)

What doesn't work?

  1. Exceptions and Throwables (experimental implementation was removed)
  2. Module constructors and destructors
  3. Static constructors and destructors
  4. Shared static constructors and destructors
  5. Module info
  6. There is no GC implementation (primitive memory tracking is now available with LWDR_TrackMem, RefCount!T and Unique!T are now available)
  7. Delegates/closures
  8. Associative arrays
  9. Object monitors
  10. shared/synchronised
  11. Object hashing
  12. Other things I can't remember off the top of my head.

It's still a beta - so expect bugs and warts. Some bits have been thoroughly tested, others not so much.

Because the runtime has ballooned so quickly, I want to pause on development for a little bit so that I can begin using LWDR in a proper project and find and squash bugs. The project is pretty much the successor to my Driving with D article (it's an automotive project). I'm also thinking of applying with LWDR to the Autumn of Code thingo.

June 19, 2021

On Saturday, 19 June 2021 at 13:31:11 UTC, Dylan Graham wrote:


Previous announcement

Once LWDR is stable enough, I want the next version to include module info, static ctor/dtor support and to look into Object monitor support and other multithreading tools (Mutexes, Conditions, etc).

July 09, 2021

Great Work! Why standard D Runtime can not run on MCU? Will you plan that LWDR support other arch like RISC-v ?

July 10, 2021
On 10/07/2021 2:30 AM, lili wrote:
> Why standard D Runtime can not run on MCU?

It requires things like threads.

Basically it assumes there is a kernel.

Anyway, you don't want the regular runtime on a MCU, a MCU is too small in memory to really hold it all and your own logic and any libraries you need for the hardware its connected to.
July 09, 2021

On Friday, 9 July 2021 at 14:30:07 UTC, lili wrote:


Great Work!



Why standard D Runtime can not run on MCU?

The standard D Runtime is reliant on a fully-fledged OS, which don't fit onto small embedded devices and they're incompatible with them For example, Linux requires a memory management unit (MMU), yet the Cortex-M series lack that feature.

The runtime itself is quite heavy due to the enormity of the features it supports. For example, the functions in DRuntime's lifetime.d are dependent on GC code, which adds memory overhead to store those instructions and stack space. In LWDR, lifetime functions just point to your own implementation, yielding a leaner memory footprint. It's a very pedantic example, but it adds up after a while on a resource-constrained platform.


Will you plan that LWDR support other arch like RISC-v ?

Yes :)

Asides from some ARM EABI specific stuff in rt/sections.d, I don't think it'd difficult getting LWDR running on another MCU platform (as of v0.3.0).