summaryrefslogtreecommitdiff
path: root/libmachdev/ds_routines.c
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-02-08 08:58:53 +0100
committerZheng Da <zhengda1936@gmail.com>2010-02-08 08:58:53 +0100
commit5ea9105dff5f22606026afcd88b178110282b224 (patch)
tree7e42a5240018310fca4e805a4df95a01c44c75e2 /libmachdev/ds_routines.c
parentaff295710ea0b575c556f10981d1ae740e192969 (diff)
remove io done thread.
eliminate a potential race condition in thread_wait and thread_wakeup.
Diffstat (limited to 'libmachdev/ds_routines.c')
-rw-r--r--libmachdev/ds_routines.c362
1 files changed, 0 insertions, 362 deletions
diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index c647b8e9..857f64c5 100644
--- a/libmachdev/ds_routines.c
+++ b/libmachdev/ds_routines.c
@@ -448,362 +448,6 @@ ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset,
return D_INVALID_OPERATION;
}
-boolean_t
-ds_open_done(ior)
- register io_req_t ior;
-{
- kern_return_t result;
- register mach_device_t device;
-
- device = ior->io_device;
- result = ior->io_error;
-
- if (result != D_SUCCESS) {
- /*
- * Open failed. Deallocate port and device.
- */
-// dev_port_remove(device);
-// ipc_port_dealloc_kernel(device->port);
-
- device_lock(device);
- device->state = DEV_STATE_INIT;
- if (device->io_wait) {
- device->io_wait = FALSE;
-// thread_wakeup((event_t)device);
- }
- device_unlock(device);
-
-// mach_device_deallocate(device);
- device = MACH_DEVICE_NULL;
- }
- else {
- /*
- * Open succeeded.
- */
- device_lock(device);
- device->state = DEV_STATE_OPEN;
- device->open_count = 1;
- if (device->io_wait) {
- device->io_wait = FALSE;
-// thread_wakeup((event_t)device);
- }
- device_unlock(device);
-
- /* donate device reference to get port */
- }
- /*
- * Must explicitly convert device to port, since
- * device_reply interface is built as 'user' side
- * (thus cannot get translation).
- */
- if (MACH_PORT_VALID(ior->io_reply_port)) {
- (void) ds_device_open_reply(ior->io_reply_port,
- ior->io_reply_port_type,
- result,
- mach_convert_device_to_port(device));
- }
-// else
-// mach_device_deallocate(device);
-
- mach_device_deallocate (device);
- return (TRUE);
-}
-
-boolean_t ds_read_done(ior)
- io_req_t ior;
-{
- vm_offset_t start_data, end_data;
- vm_offset_t start_sent, end_sent;
- register vm_size_t size_read;
-
- if (ior->io_error)
- size_read = 0;
- else
- size_read = ior->io_count - ior->io_residual;
-
- start_data = (vm_offset_t)ior->io_data;
- end_data = start_data + size_read;
-
- start_sent = (ior->io_op & IO_INBAND) ? start_data :
- trunc_page(start_data);
- end_sent = (ior->io_op & IO_INBAND) ?
- start_data + ior->io_alloc_size : round_page(end_data);
-
- /*
- * Zero memory that the device did not fill.
- */
- if (start_sent < start_data)
- memset((char *)start_sent, 0, start_data - start_sent);
- if (end_sent > end_data)
- memset((char *)end_data, 0, end_sent - end_data);
-
-
- /*
- * Touch the data being returned, to mark it dirty.
- * If the pages were filled by DMA, the pmap module
- * may think that they are clean.
- */
- {
- register vm_offset_t touch;
- register int c;
-
- for (touch = start_sent; touch < end_sent; touch += PAGE_SIZE) {
- c = *(volatile char *)touch;
- *(volatile char *)touch = c;
- }
- }
-
- /*
- * Send the data to the reply port - this
- * unwires and deallocates it.
- */
- if (ior->io_op & IO_INBAND) {
- (void)ds_device_read_reply_inband(ior->io_reply_port,
- ior->io_reply_port_type,
- ior->io_error,
- (char *) start_data,
- size_read);
- } else {
-// vm_map_copy_t copy;
-// kern_return_t kr;
-//
-// kr = vm_map_copyin_page_list(kernel_map, start_data,
-// size_read, TRUE, TRUE,
-// &copy, FALSE);
-//
-// if (kr != KERN_SUCCESS)
-// panic("read_done: vm_map_copyin_page_list failed");
-
- (void)ds_device_read_reply(ior->io_reply_port,
- ior->io_reply_port_type,
- ior->io_error,
- (char *) start_data,
- size_read);
- }
-
- /*
- * Free any memory that was allocated but not sent.
- */
- if (ior->io_count != 0) {
- if (ior->io_op & IO_INBAND) {
- if (ior->io_alloc_size > 0)
- free (ior->io_data);
-// zfree(io_inband_zone, (vm_offset_t)ior->io_data);
- } else {
- register vm_offset_t end_alloc;
-
- end_alloc = start_sent + round_page(ior->io_alloc_size);
- if (end_alloc > end_sent)
- vm_deallocate(mach_task_self (),
- end_sent,
- end_alloc - end_sent);
- }
- }
-
- mach_device_deallocate(ior->io_device);
-
- return (TRUE);
-}
-
-/*
- * Allocate wired-down memory for device read.
- */
-kern_return_t device_read_alloc(ior, size)
- register io_req_t ior;
- register vm_size_t size;
-{
- vm_offset_t addr;
- kern_return_t kr;
-
- /*
- * Nothing to do if no data.
- */
- if (ior->io_count == 0)
- return (KERN_SUCCESS);
-
- if (ior->io_op & IO_INBAND) {
- ior->io_data = (io_buf_ptr_t) malloc(sizeof(io_buf_ptr_inband_t));
- ior->io_alloc_size = sizeof(io_buf_ptr_inband_t);
- } else {
- size = round_page(size);
- kr = vm_allocate (mach_task_self (), &addr, size, TRUE);
-// kr = kmem_alloc(kernel_map, &addr, size);
- if (kr != KERN_SUCCESS)
- return (kr);
-
- ior->io_data = (io_buf_ptr_t) addr;
- ior->io_alloc_size = size;
- }
-
- return (KERN_SUCCESS);
-}
-
-struct thread_wait
-{
- struct condition cond;
- struct mutex mutex;
- int v;
-};
-
-static struct thread_wait io_done_wait;
-
-void thread_wait_init (struct thread_wait *t)
-{
- mutex_init (&t->mutex);
- condition_init (&t->cond);
- t->v = 0;
-}
-
-void thread_block (struct thread_wait *t)
-{
- mutex_lock (&t->mutex);
- t->v = 1;
- while (t->v)
- hurd_condition_wait (&t->cond, &t->mutex);
- mutex_unlock (&t->mutex);
-}
-
-void thread_wakeup (struct thread_wait *t)
-{
- mutex_lock (&t->mutex);
- t->v = 0;
- condition_signal (&t->cond);
- mutex_unlock (&t->mutex);
-}
-
-queue_head_t io_done_list;
-struct mutex io_done_list_lock;
-
-#define splio splsched /* XXX must block ALL io devices */
-
-void iodone(ior)
- register io_req_t ior;
-{
- /*
- * If this ior was loaned to us, return it directly.
- */
- if (ior->io_op & IO_LOANED) {
- (*ior->io_done)(ior);
- return;
- }
- /*
- * If !IO_CALL, some thread is waiting for this. Must lock
- * structure to interlock correctly with iowait(). Else can
- * toss on queue for io_done thread to call completion.
- */
- // TODO need a lock here?
-// s = splio();
- if ((ior->io_op & IO_CALL) == 0) {
- ior_lock(ior);
- ior->io_op |= IO_DONE;
- ior->io_op &= ~IO_WANTED;
- ior_unlock(ior);
-// thread_wakeup((event_t)ior);
- } else {
- ior->io_op |= IO_DONE;
- mutex_lock (&io_done_list_lock);
- enqueue_tail(&io_done_list, (queue_entry_t)ior);
- thread_wakeup (&io_done_wait);
-// thread_wakeup((event_t)&io_done_list);
- mutex_unlock (&io_done_list_lock);
- }
-// splx(s);
-}
-
-void wakeup_io_done_thread ()
-{
- thread_wakeup (&io_done_wait);
-}
-
-void io_done_thread_continue()
-{
- for (;;) {
- extern void free_skbuffs ();
- register io_req_t ior;
-
- free_skbuffs ();
- mutex_lock(&io_done_list_lock);
- while ((ior = (io_req_t)dequeue_head(&io_done_list)) != 0) {
- mutex_unlock(&io_done_list_lock);
-
- if ((*ior->io_done)(ior)) {
- /*
- * IO done - free io_req_elt
- */
- io_req_free(ior);
- }
- /* else routine has re-queued it somewhere */
-
- mutex_lock(&io_done_list_lock);
- }
-
-// assert_wait(&io_done_list, FALSE);
- mutex_unlock(&io_done_list_lock);
-// counter(c_io_done_thread_block++);
-// thread_block(io_done_thread_continue);
- thread_block (&io_done_wait);
- }
-}
-
-
-void
-wire_thread()
-{
- kern_return_t kr;
- mach_port_t priv_host_port;
-
- kr = get_privileged_ports (&priv_host_port, NULL);
- if (kr != KERN_SUCCESS)
- panic("get privileged port: %d", kr);
-
- kr = thread_wire(priv_host_port,
- mach_thread_self(),
- TRUE);
- if (kr != KERN_SUCCESS)
- panic("wire_thread: %d", kr);
-}
-
-void
-thread_set_own_priority (int priority)
-{
- kern_return_t kr;
- mach_port_t priv_host_port;
- mach_port_t pset, psetcntl;
-
- kr = get_privileged_ports (&priv_host_port, NULL);
- if (kr != KERN_SUCCESS)
- panic("get privileged port: %d", kr);
-
- kr = thread_get_assignment (mach_thread_self (), &pset);
- if (kr != KERN_SUCCESS)
- panic("thread get assignment: %d", kr);
- kr = host_processor_set_priv (priv_host_port, pset, &psetcntl);
- if (kr != KERN_SUCCESS)
- panic("processor set priv: %d", kr);
- kr = thread_max_priority (mach_thread_self (), psetcntl, 0);
- if (kr != KERN_SUCCESS)
- panic("set thread max priority: %d", kr);
- kr = thread_priority (mach_thread_self (), 0, FALSE);
- if (kr != KERN_SUCCESS)
- panic("set thread priority: %d", kr);
-}
-
-static any_t io_done_thread(any_t unused)
-{
- /*
- * Set thread privileges and highest priority.
- */
-// current_thread()->vm_privilege = TRUE;
-// stack_privilege(current_thread());
- wire_thread ();
-
- thread_set_own_priority(0);
-
- io_done_thread_continue();
- /*NOTREACHED*/
- return 0;
-}
-
int create_device_port (int size, void *result)
{
return ports_create_port (dev_class, port_bucket,
@@ -814,18 +458,12 @@ void mach_device_init()
{
int i;
- queue_init(&io_done_list);
- mutex_init (&io_done_list_lock);
- thread_wait_init (&io_done_wait);
-
port_bucket = ports_create_bucket ();
dev_class = ports_create_class (0, 0);
for (i = 0; i < NUM_EMULATION; i++) {
emulation_list[i]->init();
}
-
- cthread_detach (cthread_fork (io_done_thread, 0));
}
static int