www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - LWDR (Light Weight D Runtime) v0.3.0

reply Dylan Graham <dylan.graham2000 gmail.com> writes:
[Github](https://github.com/0dyl/LWDR)
[DUB](https://code.dlang.org/packages/lwdr)
[Previous 
announcement](https://forum.dlang.org/post/giigcnoyxfoxxaevjmxy forum.dlang.org)

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](https://github.com/0dyl/LWDR/blob/master/source/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 `LWDR.free(..)` 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](https://www.freertos.org/pvTaskGetThreadLocalStoragePointer.html)).
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](https://forum.dlang.org/post/gfyhdqecjxszrgutlhmi forum.dlang.org).

**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](https://dlang.org/spec/version.html). 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](https://dlang.org/deprecate.html#delete). 
`LWDR.free` 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](https://dlang.org/spec/ddoc.html) comments.

**`RefCount!T` and `Unique!T`**
To alleviate the lack of GC, I have implemented an LWDR-specific 
solution inspired by 
[automem](https://code.dlang.org/packages/automem).

**What works?**
1. Class allocations and deallocations (via `new` and `LWDR.free`)
2. Struct heap allocations and deallocations (via `new` and 
`LWDR.free`)
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](https://dlang.org/blog/2021/06/01/driving-with-d/) (it's 
an automotive project). I'm also thinking of applying with LWDR 
to the Autumn of Code thingo.
Jun 19 2021
next sibling parent Dylan Graham <dylan.graham2000 gmail.com> writes:
On Saturday, 19 June 2021 at 13:31:11 UTC, Dylan Graham wrote:
 [Github](https://github.com/0dyl/LWDR)
 [DUB](https://code.dlang.org/packages/lwdr)
 [Previous 
 announcement](https://forum.dlang.org/post/giigcnoyxfoxxaevjmxy forum.dlang.org)
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).
Jun 19 2021
prev sibling parent reply lili <akozhao tencent.com> writes:
Great Work! Why standard D Runtime can not run on MCU?  Will you 
plan that LWDR support other arch like RISC-v ?
Jul 09 2021
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
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.
Jul 09 2021
prev sibling parent Dylan Graham <dylan.graham2000 gmail.com> writes:
On Friday, 9 July 2021 at 14:30:07 UTC, lili wrote:
 Great Work!
Thanks!
 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](https://electronics.stackexchange.com/a/19243) 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`](https://github.com/dlang/druntime/blob/15b49cc725df280a72508f729ec4495ffbac66c3/sr /rt/lifetime.d#L86) are dependent on GC code, which adds memory overhead to store those instructions and stack space. In LWDR, [`lifetime`](https://github.com/hmmdyl/LWDR/tree/master/source/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`](https://github.com/hmmdyl/LWDR/blob/d55a39d028942f0eb1582d473317f89030995703/source rt/sections.d#L38), I don't think it'd difficult getting LWDR running on another MCU platform (as of v0.3.0).
Jul 09 2021