|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* IOStubThread.m 1.0 02/04/91 (c) 1991 NeXT ! 25: * ! 26: * IOStubThread.m - IOStub I/O Thread and associated methods. ! 27: * ! 28: * HISTORY ! 29: * 04-Feb-91 Doug Mitchell at NeXT ! 30: * Created. ! 31: */ ! 32: ! 33: #import <bsd/sys/types.h> ! 34: #import <driverkit/IODevice.h> ! 35: #import "IOStub.h" ! 36: #import "IOStubThread.h" ! 37: #import "IOStubPrivate.h" ! 38: #import <driverkit/DiskDeviceKern.h> ! 39: #import <bsd/dev/ldd.h> ! 40: #import <machkit/NXLock.h> ! 41: ! 42: @implementation IOStub(Thread) ! 43: ! 44: /* ! 45: * Enqueue an IOBuf on IOQueue, wake up I/O thread. Called by exported ! 46: * methods in order to make I/O requests of the I/O thread. ! 47: */ ! 48: - (void)enqueueIoBuf : (IOBuf *)buf ! 49: { ! 50: xpr_stub("enqueueIoBuf: IOBuf 0x%x\n", buf, 2,3,4,5); ! 51: [queueLock lock]; ! 52: queue_enter(&ioQueue, buf, IOBuf *, ioChain); ! 53: [queueLock unlockWith:WORK_AVAILABLE]; ! 54: } ! 55: ! 56: /* ! 57: * The rest of the methods in this module run in the I/O thread. ! 58: */ ! 59: ! 60: /* ! 61: * Get an IOBuf from IOQueue. Blocks if necessary. ! 62: */ ! 63: - (IOBuf *)dequeueIoBuf ! 64: { ! 65: IOBuf *buf; ! 66: ! 67: xpr_stub("dequeueIoBuf\n", 1,2,3,4,5); ! 68: [queueLock lockWhen:WORK_AVAILABLE]; ! 69: buf = (IOBuf *)queue_first(&ioQueue); ! 70: queue_remove(&ioQueue, buf, IOBuf *, ioChain); ! 71: if(queue_empty(&ioQueue)) ! 72: [queueLock unlockWith:NO_WORK_AVAILABLE]; ! 73: else ! 74: [queueLock unlockWith:WORK_AVAILABLE]; ! 75: return buf; ! 76: } ! 77: ! 78: /* ! 79: * Methods which do the actual "I/O" of this device. ! 80: */ ! 81: /* ! 82: * These are the methods which actually do the work of this device. All ! 83: * of these methods run in IOStub_thread. ! 84: */ ! 85: - (void)deviceRead : (IOBuf *)IOBuf ! 86: { ! 87: char *source; ! 88: ! 89: xpr_stub("deviceRead:\n", 1,2,3,4,5); ! 90: source = stub_data + (IOBuf->offset * [self blockSize]); ! 91: bcopy(source, IOBuf->buf, IOBuf->bytesReq); ! 92: IOBuf->bytesXfr = IOBuf->bytesReq; ! 93: IOBuf->status = IO_R_SUCCESS; ! 94: if(IOBuf->pending) { ! 95: /* ! 96: * Async I/O. Notify client. ! 97: */ ! 98: [self diskIoComplete:IOBuf->pending ! 99: status:IO_R_SUCCESS ! 100: bytesXfr:IOBuf->bytesXfr]; ! 101: IOFree(IOBuf, sizeof(*IOBuf)); ! 102: } ! 103: else { ! 104: /* ! 105: * Synchronous I/O. Notify sleeping thread. ! 106: */ ! 107: [IOBuf->waitLock lock]; ! 108: [IOBuf->waitLock unlockWith:YES]; ! 109: } ! 110: } ! 111: ! 112: - (void)deviceWrite : (IOBuf *)IOBuf ! 113: { ! 114: char *dest; ! 115: ! 116: xpr_stub("deviceWrite:\n", 1,2,3,4,5); ! 117: dest = stub_data + IOBuf->offset * [self blockSize]; ! 118: ! 119: bcopy(IOBuf->buf, dest, IOBuf->bytesReq); ! 120: IOBuf->bytesXfr = IOBuf->bytesReq; ! 121: IOBuf->status = IO_R_SUCCESS; ! 122: if(IOBuf->pending) { ! 123: /* ! 124: * Async I/O. Notify client. ! 125: */ ! 126: [self diskIoComplete:IOBuf->pending ! 127: status:IO_R_SUCCESS ! 128: bytesXfr:IOBuf->bytesXfr]; ! 129: IOFree(IOBuf, sizeof(*IOBuf)); ! 130: } ! 131: else { ! 132: /* ! 133: * Synchronous I/O. Notify sleeping thread. ! 134: */ ! 135: [IOBuf->waitLock lock]; ! 136: [IOBuf->waitLock unlockWith:YES]; ! 137: } ! 138: } ! 139: ! 140: ! 141: /* ! 142: * I/O thread. This is forked off in the stubInit: method. This handles ! 143: * IOBufs which have been enqueued by exported methods. ! 144: * ! 145: * This thread merely loops doing the following: ! 146: * -- get an IOBuf off of the IOQueue. ! 147: * -- perform the task specified. ! 148: * -- if async request, ioComplete: the result, else ! 149: * notify the waiting thread via IOBuf.waitLock. ! 150: */ ! 151: volatile void IOStub_thread(id stubp) ! 152: { ! 153: IOStub *stub = stubp; ! 154: IOBuf *IOBuf; ! 155: ! 156: xpr_stub("IOStub_thread: starting\n", 1,2,3,4,5); ! 157: while(1) { ! 158: IOBuf = [stub dequeueIoBuf]; ! 159: xpr_stub("IOStub_thread: IOBuf 0x%x received\n", IOBuf, ! 160: 2,3,4,5); ! 161: ! 162: switch(IOBuf->cmd) { ! 163: case STUB_READ: ! 164: [stub deviceRead:IOBuf]; ! 165: break; ! 166: case STUB_WRITE: ! 167: [stub deviceWrite:IOBuf]; ! 168: break; ! 169: case STUB_ABORT: ! 170: /* ! 171: * Time for us to exit. First I/O complete ! 172: * this request, then exit. ! 173: */ ! 174: IOBuf->status = IO_R_SUCCESS; ! 175: [IOBuf->waitLock lock]; ! 176: [IOBuf->waitLock unlockWith:YES]; ! 177: IOExitThread(); ! 178: ! 179: default: ! 180: printf("IOStub_thread: BOGUS IOBuf\n"); ! 181: break; ! 182: } ! 183: } ! 184: /* NOT REACHED */ ! 185: } ! 186: ! 187: @end ! 188: ! 189: /* end of IOStubThread.m */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.