|
|
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.