1 /*******************************************************************************
2 
3     Reusable fiber pool implementation
4 
5     Copyright:
6         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7         All rights reserved.
8 
9     License:
10         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11         Alternatively, this file may be distributed under the terms of the Tango
12         3-Clause BSD License (see LICENSE_BSD.txt for details).
13 
14 *******************************************************************************/
15 
16 module ocean.task.internal.FiberPool;
17 
18 
19 import core.thread;
20 
21 import ocean.task.Task;
22 import ocean.core.Verify;
23 import ocean.util.container.pool.ObjectPool;
24 
25 debug (TaskScheduler)
26 {
27     import ocean.io.Stdout;
28 }
29 
30 /******************************************************************************
31 
32     Fiber pool class.
33 
34     Allows recycling finished fibers, reusing them to spawn new tasks without
35     making new allocations.
36 
37 ******************************************************************************/
38 
39 public class FiberPool : ObjectPool!(WorkerFiber)
40 {
41     /**************************************************************************
42 
43         Fiber stack size defined for this pool
44 
45     **************************************************************************/
46 
47     private size_t stack_size;
48 
49     /**************************************************************************
50 
51         Constructor
52 
53         Params:
54             stack_size = fiber stack size to use in this poll
55             limit = limit to pool size. If set to 0 (default), there is no
56                 app limit and pool growth will be limited only by OS
57                 resources
58 
59     **************************************************************************/
60 
61     this ( size_t stack_size, size_t limit = 0 )
62     {
63         this.stack_size = stack_size;
64         if (limit > 0)
65             this.setLimit(limit);
66     }
67 
68     /**************************************************************************
69 
70         This method should never be called, it is only overridden to conform
71         to base class API. Other modules in `ocean.task` package only
72         used other `get` overload.
73 
74         Params:
75             if_missing = lazy expression that creates new fiber in case
76                 pool needs to be extended
77 
78         Returns:
79             Fiber reference to use. Can be either reused or freshly created
80             one. Null upon any failure.
81 
82     **************************************************************************/
83 
84     override public WorkerFiber get ( lazy WorkerFiber if_missing )
85     {
86         auto fiber = super.get(if_missing);
87         if (fiber is null)
88             return null;
89         verify(fiber.state() == Fiber.State.TERM);
90         return fiber;
91     }
92 
93     /**************************************************************************
94 
95         The method to get a fiber from the pool.
96 
97         Returns:
98             Fiber reference to use. Can be either reused or freshly created
99             one. Null upon any failure.
100 
101     **************************************************************************/
102 
103     public WorkerFiber get ( )
104     {
105         return this.get(new WorkerFiber(this.stack_size));
106     }
107 
108     /**************************************************************************
109 
110         Resets recycled item state to make it usable again.
111 
112         Doesn't actually do anything apart from checking fiber state to avoid
113         fiber attempts to reset other running fiber. When scheduler gets an
114         item from the pool, it will reset it to new task anyway.
115 
116         Params:
117             item = item (fiber) to reset
118 
119     **************************************************************************/
120 
121     override protected void resetItem ( Item item )
122     {
123         auto fiber = this.fromItem(item);
124         verify(
125             fiber is Fiber.getThis()
126                 || fiber.state() == Fiber.State.TERM
127         );
128     }
129 }