]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOCommandPool.cpp
xnu-792.6.56.tar.gz
[apple/xnu.git] / iokit / Kernel / IOCommandPool.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ff6e181a
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
1c79356b 12 *
ff6e181a
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ff6e181a
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
1c79356b
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 *
26 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
27 *
28 * HISTORY
29 *
30 * 2001-01-17 gvdl Re-implement on IOCommandGate::commandSleep
31 * 10/9/2000 CJS Created IOCommandPool class and implementation
32 *
33 */
34
35#include <IOKit/IOCommandPool.h>
36
37#define super OSObject
38OSDefineMetaClassAndStructors(IOCommandPool, OSObject);
39OSMetaClassDefineReservedUnused(IOCommandPool, 0);
40OSMetaClassDefineReservedUnused(IOCommandPool, 1);
41OSMetaClassDefineReservedUnused(IOCommandPool, 2);
42OSMetaClassDefineReservedUnused(IOCommandPool, 3);
43OSMetaClassDefineReservedUnused(IOCommandPool, 4);
44OSMetaClassDefineReservedUnused(IOCommandPool, 5);
45OSMetaClassDefineReservedUnused(IOCommandPool, 6);
46OSMetaClassDefineReservedUnused(IOCommandPool, 7);
47
48//--------------------------------------------------------------------------
49// withWorkLoop - primary initializer and factory method
50//--------------------------------------------------------------------------
51
52IOCommandPool *IOCommandPool::
53withWorkLoop(IOWorkLoop *inWorkLoop)
54{
55 IOCommandPool * me = new IOCommandPool;
56
57 if (me && !me->initWithWorkLoop(inWorkLoop)) {
58 me->release();
59 return 0;
60 }
61
62 return me;
63}
64
65
66bool IOCommandPool::
67initWithWorkLoop(IOWorkLoop *inWorkLoop)
68{
69 assert(inWorkLoop);
70
71 if (!super::init())
72 return false;
73
74 queue_init(&fQueueHead);
75
76 fSerializer = IOCommandGate::commandGate(this);
77 assert(fSerializer);
78 if (!fSerializer)
79 return false;
80
81 if (kIOReturnSuccess != inWorkLoop->addEventSource(fSerializer))
82 return false;
83
84 return true;
85}
86
87//--------------------------------------------------------------------------
88// commandPool & init - obsolete initializer and factory method
89//--------------------------------------------------------------------------
90
91IOCommandPool *IOCommandPool::
92commandPool(IOService * inOwner, IOWorkLoop *inWorkLoop, UInt32 inSize)
93{
94 IOCommandPool * me = new IOCommandPool;
95
96 if (me && !me->init(inOwner, inWorkLoop, inSize)) {
97 me->release();
98 return 0;
99 }
100
101 return me;
102}
103
104bool IOCommandPool::
105init(IOService */* inOwner */, IOWorkLoop *inWorkLoop, UInt32 /* inSize */)
106{
107 return initWithWorkLoop(inWorkLoop);
108}
109
110
111//--------------------------------------------------------------------------
112// free - free all allocated resources
113//--------------------------------------------------------------------------
114
115void
116IOCommandPool::free(void)
117{
118 if (fSerializer) {
119 // remove our event source from owner's workloop
120 IOWorkLoop *wl = fSerializer->getWorkLoop();
121 if (wl)
122 wl->removeEventSource(fSerializer);
123
124 fSerializer->release();
125 fSerializer = 0;
126 }
127
128 // Tell our superclass to cleanup too
129 super::free();
130}
131
132
133//--------------------------------------------------------------------------
134// getCommand - Gets a command from the pool. Pass true in
135// blockForCommand if you want your thread to sleep
136// waiting for resources
137//--------------------------------------------------------------------------
138
139IOCommand *
140IOCommandPool::getCommand(bool blockForCommand)
141{
142 IOReturn result = kIOReturnSuccess;
143 IOCommand *command = 0;
144
145 result = fSerializer->runAction((IOCommandGate::Action)
146 &IOCommandPool::gatedGetCommand,
147 (void *) &command, (void *) blockForCommand);
148 if (kIOReturnSuccess == result)
149 return command;
150 else
151 return 0;
152}
153
154
155//--------------------------------------------------------------------------
156// gatedGetCommand - Static callthrough function
157// (on safe side of command gate)
158//--------------------------------------------------------------------------
159
160IOReturn IOCommandPool::
161gatedGetCommand(IOCommand **command, bool blockForCommand)
162{
163 while (queue_empty(&fQueueHead)) {
164 if (!blockForCommand)
165 return kIOReturnNoResources;
166
167 fSleepers++;
168 fSerializer->commandSleep(&fSleepers, THREAD_UNINT);
169 }
170
171 queue_remove_first(&fQueueHead,
172 *command, IOCommand *, fCommandChain);
173 return kIOReturnSuccess;
174}
175
176
177//--------------------------------------------------------------------------
178// returnCommand - Returns command to the pool.
179//--------------------------------------------------------------------------
180
181void IOCommandPool::
182returnCommand(IOCommand *command)
183{
184 (void) fSerializer->runAction((IOCommandGate::Action)
185 &IOCommandPool::gatedReturnCommand, (void *) command);
186}
187
188
189//--------------------------------------------------------------------------
190// gatedReturnCommand - Callthrough function
191// (on safe side of command gate)
192//--------------------------------------------------------------------------
193
194IOReturn IOCommandPool::
195gatedReturnCommand(IOCommand *command)
196{
197 queue_enter(&fQueueHead, command, IOCommand *, fCommandChain);
198 if (fSleepers) {
199 fSerializer->commandWakeup(&fSleepers, /* oneThread */ true);
200 fSleepers--;
201 }
202 return kIOReturnSuccess;
203}