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