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 }