📄 ide-hd-multithread
字号:
Index: ioemu/hw/ide.c===================================================================--- ioemu.orig/hw/ide.c 2007-05-03 15:03:18.000000000 +0100+++ ioemu/hw/ide.c 2007-05-03 15:06:48.000000000 +0100@@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "vl.h"+#include <pthread.h> /* debug IDE devices */ //#define DEBUG_IDE@@ -390,6 +391,89 @@ int type; /* see IDE_TYPE_xxx */ } PCIIDEState; +#define DMA_MULTI_THREAD++#ifdef DMA_MULTI_THREAD++static pthread_t ide_dma_thread;+static int file_pipes[2];++static void ide_dma_loop(BMDMAState *bm);+static void dma_thread_loop(BMDMAState *bm);++extern int suspend_requested;+static void *dma_thread_func(void* opaque)+{+ BMDMAState* req;+ fd_set fds;+ int rv, nfds = file_pipes[0] + 1;+ struct timeval tm;++ while (1) {++ /* Wait at most a second for the pipe to become readable */+ FD_ZERO(&fds);+ FD_SET(file_pipes[0], &fds);+ tm.tv_sec = 1;+ tm.tv_usec = 0;+ rv = select(nfds, &fds, NULL, NULL, &tm);+ + if (rv != 0) {+ if (read(file_pipes[0], &req, sizeof(req)) == 0)+ return NULL;+ dma_thread_loop(req);+ } else {+ if (suspend_requested) {+ /* Need to tidy up the DMA thread so that we don't end up + * finishing operations after the domain's ioreqs are + * drained and its state saved */+ return NULL;+ }+ }+ }++ return NULL;+}++static void dma_create_thread(void)+{+ int rt;+ pthread_attr_t a;++ if (pipe(file_pipes) != 0) {+ fprintf(stderr, "create pipe failed\n");+ exit(1);+ }++ if ((rt = pthread_attr_init(&a))+ || (rt = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE))) {+ fprintf(stderr, "Oops, dma thread attr setup failed, errno=%d\n", rt);+ exit(1);+ } + + if ((rt = pthread_create(&ide_dma_thread, &a, dma_thread_func, NULL))) {+ fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt);+ exit(1);+ }+}++void ide_stop_dma_thread(void)+{+ int rc;+ /* Make sure the IDE DMA thread is stopped */+ if ( (rc = pthread_join(ide_dma_thread, NULL)) != 0 )+ {+ fprintf(stderr, "Oops, error collecting IDE DMA thread (%s)\n", + strerror(rc));+ }+}++#else+void ide_stop_dma_thread(void)+{+}+#endif /* DMA_MULTI_THREAD */+ static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); static void padstr(char *str, const char *src, int len)@@ -695,7 +779,9 @@ } if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) { s->status = READY_STAT | SEEK_STAT;+#ifndef DMA_MULTI_THREAD ide_set_irq(s);+#endif /* !DMA_MULTI_THREAD */ #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); #endif@@ -795,7 +881,11 @@ qemu_get_clock(vm_clock) + (ticks_per_sec / 1000)); } else #endif+#ifndef DMA_MULTI_THREAD ide_set_irq(s);+#else /* !DMA_MULTI_THREAD */+ ;+#endif /* DMA_MULTI_THREAD */ return 0; } if (n > MAX_MULT_SECTORS)@@ -1046,7 +1136,9 @@ if (s->packet_transfer_size <= 0) { s->status = READY_STAT; s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;+#ifndef DMA_MULTI_THREAD ide_set_irq(s);+#endif /* !DMA_MULTI_THREAD */ #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); #endif@@ -2103,9 +2195,30 @@ } } +static void ide_dma_finish(BMDMAState *bm)+{+ IDEState *s = bm->ide_if;++ bm->status &= ~BM_STATUS_DMAING;+ bm->status |= BM_STATUS_INT;+ bm->dma_cb = NULL;+ bm->ide_if = NULL;+#ifdef DMA_MULTI_THREAD+ ide_set_irq(s);+#endif /* DMA_MULTI_THREAD */+}+ /* XXX: full callback usage to prepare non blocking I/Os support - error handling */+#ifdef DMA_MULTI_THREAD+static void ide_dma_loop(BMDMAState *bm)+{+ write(file_pipes[1], &bm, sizeof(bm));+}+static void dma_thread_loop(BMDMAState *bm)+#else /* DMA_MULTI_THREAD */ static void ide_dma_loop(BMDMAState *bm)+#endif /* !DMA_MULTI_THREAD */ { struct { uint32_t addr;@@ -2141,10 +2254,7 @@ } /* end of transfer */ the_end:- bm->status &= ~BM_STATUS_DMAING;- bm->status |= BM_STATUS_INT;- bm->dma_cb = NULL;- bm->ide_if = NULL;+ ide_dma_finish(bm); } static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)@@ -2370,6 +2480,9 @@ cmd646_set_irq, d, 0); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], cmd646_set_irq, d, 1);+#ifdef DMA_MULTI_THREAD + dma_create_thread();+#endif /* DMA_MULTI_THREAD */ } static void pci_ide_save(QEMUFile* f, void *opaque)@@ -2522,6 +2635,10 @@ register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d); register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);++#ifdef DMA_MULTI_THREAD + dma_create_thread();+#endif //DMA_MULTI_THREAD } /***********************************************************/Index: ioemu/target-i386-dm/helper2.c===================================================================--- ioemu.orig/target-i386-dm/helper2.c 2007-05-03 15:03:18.000000000 +0100+++ ioemu/target-i386-dm/helper2.c 2007-05-03 15:06:41.000000000 +0100@@ -556,6 +556,9 @@ handle_buffered_io(env); main_loop_wait(1); /* For the select() on events */ + /* Stop the IDE thread */+ ide_stop_dma_thread();+ /* Save the device state */ sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid); if (qemu_savevm(qemu_file) < 0)Index: ioemu/vl.h===================================================================--- ioemu.orig/vl.h 2007-05-03 15:03:18.000000000 +0100+++ ioemu/vl.h 2007-05-03 15:06:42.000000000 +0100@@ -797,6 +797,7 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn); int pmac_ide_init (BlockDriverState **hd_table, SetIRQFunc *set_irq, void *irq_opaque, int irq);+void ide_stop_dma_thread(void); /* cdrom.c */ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -