|
|
1.1 root 1: /*
2: * Copyright (c) 1998-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: #if DEBUG
23:
24: #include "Tests.h"
25:
26: #include <IOKit/IOCommandQueue.h>
27: #include <IOKit/IOInterruptEventSource.h>
28: #include <IOKit/IOWorkLoop.h>
29:
30: #include <mach/sync_policy.h>
31:
32: #define super OSObject
33:
34: static TestDevice *sDevice;
35:
36: static mach_timespec_t hundredMill = { 0, 100000000 };
37: static semaphore_port_t completeSema;
38:
39: OSDefineMetaClassAndStructors(TestDevice, OSObject)
40:
41: kern_return_t
42: TestDevice::enqueueCommand(bool sleep,
43: TestDeviceAction act, int tag, void *dataP)
44: {
45: return commQ->enqueueCommand(sleep, (void *) act, (void *) tag, dataP);
46: }
47:
48: bool TestDevice::init()
49: {
50: if ( !super::init() )
51: return false;
52:
53: workLoop = IOWorkLoop::workLoop();
54: if ( !workLoop )
55: return false;
56:
57: commQ = IOCommandQueue::commandQueue
58: (this, (IOCommandQueueAction) &rawCommandOccurred, 8);
59: if (!commQ || kIOReturnSuccess != workLoop->addEventSource(commQ))
60: return false;
61:
62: intES = IOInterruptEventSource::interruptEventSource
63: (this, (IOInterruptEventAction) &interruptAction);
64: if (!intES || kIOReturnSuccess != workLoop->addEventSource(intES))
65: return false;
66:
67: return true;
68: }
69:
70: void TestDevice::free()
71: {
72: if (intES) intES->release();
73: if (commQ) commQ->release();
74: if (workLoop) workLoop->release();
75:
76: super::free();
77: }
78:
79: void
80: TestDevice::rawCommandOccurred
81: (void *field0, void *field1, void *field2, void *)
82: {
83: (*(TestDeviceAction) field0)(this, (int) field1, field2);
84: }
85:
86: void
87: TestDevice::interruptAction(IOInterruptEventSource *, int count)
88: {
89: logPrintf(("I(%d, %d) ", count, ++intCount));
90: }
91:
92: void
93: TestDevice::producer1Action(int tag)
94: {
95: logPrintf(("C1(%d) ", tag));
96: }
97:
98: void
99: TestDevice::producer2Action(int tag, void *count)
100: {
101: logPrintf(("C2(%d,%d) ", tag, (int) count));
102: if ( !(tag % 10) )
103: IOSleep(1000);
104: }
105:
106: void
107: TestDevice::alarm()
108: {
109: intES->interruptOccurred(0, 0, 0);
110: IOScheduleFunc((IOThreadFunc) alarm, (void *) this, hundredMill, 1);
111: }
112:
113: static void producer(void *inProducerId)
114: {
115: int producerId = (int) inProducerId;
116: TestDeviceAction command;
117: int i;
118:
119: semaphore_wait(completeSema);
120:
121: if (producerId & 1)
122: command = (TestDeviceAction) sDevice->producer1Action;
123: else
124: command = (TestDeviceAction) sDevice->producer2Action;
125:
126: for (i = 0; i < 5 * (producerId << 1); i++) {
127: sDevice->enqueueCommand
128: (true, command, i, (void *) (i % (producerId + 1)));
129: if ( !(i % (producerId + 1)) )
130: /* cthread_yield() */;
131: logPrintf(("TestDevice(%d): %d\n", producerId, i));
132: }
133:
134: logPrintf(("TestDevice: producer %d exiting\n", producerId));
135: semaphore_signal(completeSema);
136:
137: IOExitThread(producerId);
138: }
139:
140: void testWorkLoop()
141: {
142: int i;
143:
144: sDevice = new TestDevice;
145: if (!sDevice || !sDevice->init()) {
146: if (sDevice) sDevice->free();
147: logPrintf(("TestDevice: couldn't create device instance\n"));
148: return;
149: }
150:
151: IOSleep(1000);
152:
153: IOScheduleFunc((IOThreadFunc) sDevice->alarm, sDevice, hundredMill, 1);
154:
155: IOSleep(2000);
156:
157: if (KERN_SUCCESS
158: != semaphore_create(kernel_task, &completeSema, SYNC_POLICY_FIFO, 4))
159: return;
160:
161: IOCreateThread(producer, (void *) 4);
162: IOCreateThread(producer, (void *) 3);
163: IOCreateThread(producer, (void *) 2);
164: IOCreateThread(producer, (void *) 1);
165:
166: IOSleep(2000);
167:
168: for (i = 0; i < 4; i++)
169: semaphore_wait(completeSema);
170:
171: IOUnscheduleFunc((IOThreadFunc) sDevice->alarm, sDevice);
172:
173: sDevice->free(); sDevice = 0;
174:
175: logPrintf(("TestDevice: exiting\n"));
176: }
177:
178: #endif /* DEBUG */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.