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 }