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