]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOCommandPool.cpp
xnu-344.49.tar.gz
[apple/xnu.git] / iokit / Kernel / IOCommandPool.cpp
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
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
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
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
40 OSDefineMetaClassAndStructors(IOCommandPool, OSObject);
41 OSMetaClassDefineReservedUnused(IOCommandPool, 0);
42 OSMetaClassDefineReservedUnused(IOCommandPool, 1);
43 OSMetaClassDefineReservedUnused(IOCommandPool, 2);
44 OSMetaClassDefineReservedUnused(IOCommandPool, 3);
45 OSMetaClassDefineReservedUnused(IOCommandPool, 4);
46 OSMetaClassDefineReservedUnused(IOCommandPool, 5);
47 OSMetaClassDefineReservedUnused(IOCommandPool, 6);
48 OSMetaClassDefineReservedUnused(IOCommandPool, 7);
49
50 //--------------------------------------------------------------------------
51 // withWorkLoop - primary initializer and factory method
52 //--------------------------------------------------------------------------
53
54 IOCommandPool *IOCommandPool::
55 withWorkLoop(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
68 bool IOCommandPool::
69 initWithWorkLoop(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
93 IOCommandPool *IOCommandPool::
94 commandPool(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
106 bool IOCommandPool::
107 init(IOService */* inOwner */, IOWorkLoop *inWorkLoop, UInt32 /* inSize */)
108 {
109 return initWithWorkLoop(inWorkLoop);
110 }
111
112
113 //--------------------------------------------------------------------------
114 // free - free all allocated resources
115 //--------------------------------------------------------------------------
116
117 void
118 IOCommandPool::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
141 IOCommand *
142 IOCommandPool::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
162 IOReturn IOCommandPool::
163 gatedGetCommand(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
183 void IOCommandPool::
184 returnCommand(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
196 IOReturn IOCommandPool::
197 gatedReturnCommand(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 }