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