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.stdc.stdlib:malloc,free; 9 import core.stdc.string:memset,memcpy; 10 import core.atomic; 11 import core.thread:Fiber,Thread,PAGESIZE; 12 import core.memory; 13 14 import mutils.job_manager.shared_utils; 15 16 //only one warning about GC 17 Fiber newFiber(){ 18 static void dummy(){} 19 Fiber fiber = new Fiber(&dummy,PAGESIZE * 32u); 20 GC.addRoot(cast(void*)fiber); 21 fiber.call(); 22 return fiber; 23 } 24 25 class FiberNoCache{ 26 27 Fiber getData(uint,uint){ 28 Fiber fiber = newFiber(); 29 return fiber; 30 } 31 32 void removeData(Fiber obj,uint,uint){ 33 GC.removeRoot(cast(void*)obj); 34 } 35 36 } 37 38 class FiberOneCache{ 39 static void dummy(){} 40 41 static Fiber lastFreeFiber;//1 element tls cache 42 43 Fiber getData(uint,uint){ 44 Fiber fiber; 45 if(lastFreeFiber is null){ 46 fiber = newFiber(); 47 }else{ 48 fiber=lastFreeFiber; 49 lastFreeFiber=null; 50 } 51 return fiber; 52 } 53 54 void removeData(Fiber obj,uint,uint){ 55 if(lastFreeFiber !is null){ 56 GC.removeRoot(cast(void*)lastFreeFiber); 57 Mallocator.instance.dispose(lastFreeFiber); 58 } 59 lastFreeFiber=obj; 60 } 61 } 62 63 import mutils.container.vector; 64 static Vector!Fiber array; 65 static uint used=0; 66 67 void initializeFiberCache(){ 68 array.reserve(16); 69 } 70 71 class FiberTLSCache{ 72 73 this(){} 74 75 Fiber getData(uint,uint){ 76 Fiber fiber; 77 if(array.length<=used){ 78 fiber= newFiber(); 79 array~=fiber; 80 used++; 81 return fiber; 82 } 83 fiber=array[used]; 84 used++; 85 return fiber; 86 } 87 88 void removeData(Fiber obj,uint,uint){ 89 foreach(i,fiber;array){ 90 if(obj == fiber){ 91 array[i]=array[used-1]; 92 array[used-1]=obj; 93 used--; 94 return; 95 } 96 } 97 assert(0); 98 } 99 } 100 101 102