1 module lifetime.delegate_; 2 3 pragma(LDC_no_moduleinfo); 4 5 import lwdr.internal.arr; 6 import lwdr.tracking; 7 8 version(LWDR_ManualDelegate): 9 10 version(LWDR_ManualDelegate_16Dels) 11 private enum numDelegatesTrack = 16; // Can track 16 delegate contexts, maximum 12 version(LWDR_ManualDelegate_32Dels) 13 private enum numDelegatesTrack = 32; // Can track 32 delegate contexts, maximum 14 version(LWDR_ManualDelegate_64Dels) 15 private enum numDelegatesTrack = 64; // Can track 64 delegate contexts, maximum 16 else 17 private enum numDelegatesTrack = 8; // Can track 8 delegate contexts, maximum 18 19 /// Keeps track of delegate context allocations 20 private __gshared LLArray delegateContextAllocations; 21 22 /++ 23 Allocate `sz` amount of bytes for a delegate context. 24 The ptr to the context will be stored in an internal array 25 for book keeping. 26 ++/ 27 extern(C) void* _d_allocmemory(size_t sz) @trusted 28 { 29 void* ptr = lwdrInternal_alloc(sz); 30 bool added = delegateContextAllocations.add(ptr); 31 assert(added); // Panic if out of room to store the context 32 return ptr; 33 } 34 35 /++ 36 Deallocate the context for a delegate. If the pointer isn't valid, 37 then no action is taken. Hence, it is safe to call this for all types 38 of delegate context types. 39 ++/ 40 void freeDelegate(void* contextPtr) @trusted nothrow 41 { 42 if(delegateContextAllocations.invalidate(contextPtr)) 43 { 44 import lifetime.common; 45 _d_delmemory(&contextPtr); 46 } 47 } 48 49 /// INTERNAL LWDR USE! Allocates the book keeping system for delegate context allocations. 50 void __lwdr_initLifetimeDelegate() @system nothrow 51 { 52 delegateContextAllocations = LLArray(numDelegatesTrack); 53 } 54 55 /// INTERNAL LWDR USE! Deallocates the book keeping system and any residual contexts. 56 void __lwdr_deinitLifetimeDelegate() @system nothrow 57 { 58 foreach(ref size_t ptr; delegateContextAllocations.unsafeRange) 59 { 60 // If the runtime is exiting, assume safe to unload any memory not already freed 61 import lifetime.common; 62 _d_delmemory(cast(void**)&ptr); 63 } 64 delegateContextAllocations.dealloc; 65 }