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