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