1 /** 2 Containers used to store Fiber objects. 3 Allocating new Fiber is expensive so need for this containers. 4 There are few implementations which can be easly changed and tested for performance or correctness. 5 */ 6 module mutils.job_manager.fiber_cache; 7 8 import core.atomic; 9 import core.memory; 10 import core.stdc.stdlib : free, malloc; 11 import core.stdc..string : memcpy, memset; 12 import std.experimental.allocator; 13 import std.experimental.allocator.mallocator; 14 15 import mutils.container.vector; 16 import mutils.job_manager.manager_utils; 17 import mutils.thread : Fiber, PAGESIZE, Thread; 18 19 //only one warning about GC 20 Fiber newFiber() { 21 Fiber fiber = Mallocator.instance.make!(Fiber)(PAGESIZE * 64); 22 fiber.state = Fiber.State.TERM; 23 return fiber; 24 } 25 26 struct FiberTLSCache { 27 28 align(64) Vector!Fiber array; 29 align(64) uint used = 0; 30 31 void clear() { 32 array.clear(); 33 used = 0; 34 } 35 36 Fiber getData() { 37 Fiber fiber; 38 if (array.length <= used) { 39 fiber = newFiber(); 40 array ~= fiber; 41 used++; 42 return fiber; 43 } 44 fiber = array[used]; 45 used++; 46 return fiber; 47 } 48 49 void removeData(Fiber obj) { 50 foreach (i, fiber; array) { 51 if (cast(void*) obj == cast(void*) fiber) { 52 array[i] = array[used - 1]; 53 array[used - 1] = obj; 54 used--; 55 return; 56 } 57 } 58 assert(0); 59 } 60 }