]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOCommandPool.cpp
5376591ce284ffae61ae4a9f543f2d407ea33466
[apple/xnu.git] / iokit / Kernel / IOCommandPool.cpp
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
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@
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
45 OSDefineMetaClassAndStructors(IOCommandPool, OSObject);
46 OSMetaClassDefineReservedUnused(IOCommandPool, 0);
47 OSMetaClassDefineReservedUnused(IOCommandPool, 1);
48 OSMetaClassDefineReservedUnused(IOCommandPool, 2);
49 OSMetaClassDefineReservedUnused(IOCommandPool, 3);
50 OSMetaClassDefineReservedUnused(IOCommandPool, 4);
51 OSMetaClassDefineReservedUnused(IOCommandPool, 5);
52 OSMetaClassDefineReservedUnused(IOCommandPool, 6);
53 OSMetaClassDefineReservedUnused(IOCommandPool, 7);
54
55 //--------------------------------------------------------------------------
56 // withWorkLoop - primary initializer and factory method
57 //--------------------------------------------------------------------------
58
59 IOCommandPool *IOCommandPool::
60 withWorkLoop(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
73 bool IOCommandPool::
74 initWithWorkLoop(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
98 IOCommandPool *IOCommandPool::
99 commandPool(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
111 bool IOCommandPool::
112 init(IOService */* inOwner */, IOWorkLoop *inWorkLoop, UInt32 /* inSize */)
113 {
114 return initWithWorkLoop(inWorkLoop);
115 }
116
117
118 //--------------------------------------------------------------------------
119 // free - free all allocated resources
120 //--------------------------------------------------------------------------
121
122 void
123 IOCommandPool::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
146 IOCommand *
147 IOCommandPool::getCommand(bool blockForCommand)
148 {
149 IOReturn result = kIOReturnSuccess;
150 IOCommand *command = 0;
151
152 IOCommandGate::Action func = OSMemberFunctionCast(
153 IOCommandGate::Action, this, &IOCommandPool::gatedGetCommand);
154 result = fSerializer->
155 runAction(func, (void *) &command, (void *) blockForCommand);
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
168 IOReturn IOCommandPool::
169 gatedGetCommand(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
189 void IOCommandPool::
190 returnCommand(IOCommand *command)
191 {
192 IOCommandGate::Action func = OSMemberFunctionCast(
193 IOCommandGate::Action, this, &IOCommandPool::gatedReturnCommand);
194 (void) fSerializer->runAction(func, (void *) command);
195 }
196
197
198 //--------------------------------------------------------------------------
199 // gatedReturnCommand - Callthrough function
200 // (on safe side of command gate)
201 //--------------------------------------------------------------------------
202
203 IOReturn IOCommandPool::
204 gatedReturnCommand(IOCommand *command)
205 {
206 queue_enter_first(&fQueueHead, command, IOCommand *, fCommandChain);
207 if (fSleepers) {
208 fSerializer->commandWakeup(&fSleepers, /* oneThread */ true);
209 fSleepers--;
210 }
211 return kIOReturnSuccess;
212 }