Source Code
Plan
Proposal
SAOC Projects
Light Weight D Runtime.
22nd September, 2021.
Symmetry Autumn of Code, Week 1 of Milestone 1.
Hi all,
Sadly, this week has not been very productive. My university is 3/4 through the semester and our "mid" semester break is next week, so my tutors have been cramming assignments into this week. Fortunately, next week I will have ample time, and in the final 1/4 of the semester I only have two assignments. My workload will be easier and I can achieve more.
During the week I worked through items for task 3 - manual deallocation of delegates/closures. Delegates may store some stack context information on the heap, and it is exposed via a delegate's ptr
property. It may or may not be context information - it could instead be a class reference or struct pointer, etc. Thus LWDR discriminates between what the ptr
actually stores and only frees the stack context information. This heap space is allocated with _d_allocmemory
. Normally, the GC would be responsible for freeing this space, instead LWDR will provides a function so the programmer can manually free the allocation.
The supporting code is in the module lifetime.delegate_
. The system is opt-in via the compile time version LWDR_ManualDelegate
. _d_allocmemory
was implemented. LWDR stores a pointer to the allocated memory in an internal list. When the programmer is done with the delegate, they can call lwdr.LWDR.freeDelegateContext
, which calls an internal function that checks if the pointer is in its list, and if so, frees the memory via a call to _d_delmemory
. This means that any delegate can be passed to this function - it will only delete copies of the stack context information. Initialisation and de-initialisation code (invoked at runtime start and stop) is implemented to allocate space for the list, and to deallocate the list and any residual delegate allocations.
As for the keeping track of the allocations, an array is allocated. Insertions and deletions are handled with atomic compare-and-swap operations, as multiple threads and even multiple cores can concurrently allocate and deallocate. If the list is full, LWDR panics. The pointers are stored as size_t
s, as CAS operations don't work with void*
. A singly-linked list was also considered, but rejected as it could cause memory fragmentation issues on memory-constrained systems. The caveat of the current approach is that there is a limit on the number of delegate contexts LWDR can keep track of (selectable at compile-time). I think a singly-linked list of arrays may be a suitable tradeoff between the two approaches, but looks like it could rely on thread blocking operations. I will look into this after tasks 1 and 2 are complete.
Due to linker issues, I have attempted to make functions @nothrow
where possible. The root was code that calls destructors in arrays. Once exception handling is implemented, this behaviour will/may(??) need to be selectable, since @nothrow
functions won't run destructor calls on an exception path, unless a way around is found. Unless, I implement the stub the linker was complaining about and avoid trying to make things @nothrow
, as I'm probably just making more work for myself. As you can tell, this area needs to be fleshed out.
All the best,
Dylan Graham.