|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993,1991,1990,1989,1988 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26:
27: #include "ds_request.h"
28:
29: #include <machine/spl.h>
30: #include <kern/counters.h>
31: #include <kern/queue.h>
32: #include <kern/zalloc.h>
33:
34:
35: queue_head_t device_ready_queue;
36: decl_simple_lock_data(, device_ready_queue_lock)
37:
38: zone_t io_req_zone;
39:
40:
41: void io_done_thread_continue()
42: {
43: for (;;) {
44: register spl_t s;
45: device_t dev;
46:
47: while (1)
48: {
49: s = splio();
50: simple_lock(&device_ready_queue_lock);
51:
52: if (queue_empty (&device_ready_queue))
53: break;
54: queue_remove_first (&device_ready_queue, dev,
55: device_t, com.stream.ready_queue);
56:
57: /* Clear this link to indicate that the device is no
58: longer on the queue, so ds_device_ready (below)
59: can check and avoid trying to requeue a device
60: that is already waiting for us on the queue. */
61: dev->com.stream.ready_queue.next = 0;
62:
63: simple_unlock(&device_ready_queue_lock);
64: (void) splx(s);
65:
66: /* We have a ready device. */
67: ds_asyncio_ready (dev);/* could be dev->ops->ready */
68: device_deallocate (dev); /* place on ready queue held a ref */
69: }
70:
71: assert_wait(&device_ready_queue, FALSE);
72: simple_unlock(&device_ready_queue_lock);
73: (void) splx(s);
74: counter(c_io_done_thread_block++);
75: thread_block(io_done_thread_continue);
76: }
77: }
78:
79: void io_done_thread()
80: {
81: /*
82: * Set thread privileges and highest priority.
83: */
84: current_thread()->vm_privilege = TRUE;
85: stack_privilege(current_thread());
86: thread_set_own_priority(0);
87:
88: io_done_thread_continue();
89: /*NOTREACHED*/
90: }
91:
92:
93: void
94: ds_device_ready (device_t dev)
95: {
96: spl_t s;
97: int ref;
98:
99: s = splio ();
100: simple_lock (&device_ready_queue_lock); /* locks all request queues! */
101:
102: ref = (dev->com.stream.ready_queue.next == 0);
103: if (ref) /* if not already on the queue */
104: queue_enter (&device_ready_queue, dev, device_t, com.stream.ready_queue);
105:
106: simple_unlock (&device_ready_queue_lock);
107: splx (s);
108:
109: /* The device's spot on the ready queue holds a reference that
110: will be freed when it's dequeued. */
111: device_reference (dev);
112:
113: thread_wakeup_one (&device_ready_queue);
114: }
115:
116: void
117: ds_request_init (void)
118: {
119: io_req_zone = zinit (sizeof (struct pending_request),
120: 1000 * sizeof (struct pending_request),
121: 100 * sizeof (struct pending_request),
122: ZONE_EXHAUSTIBLE,
123: "io requests pending");
124:
125: queue_init (&device_ready_queue);
126: simple_lock_init (&device_ready_queue_lock);
127: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.