⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vl.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
        itv.it_interval.tv_sec = 0;        itv.it_interval.tv_usec = 999; /* for i386 kernel 2.6 to get 1 ms */        itv.it_value.tv_sec = 0;        itv.it_value.tv_usec = 10 * 1000;        setitimer(ITIMER_REAL, &itv, NULL);        /* we probe the tick duration of the kernel to inform the user if           the emulated kernel requested a too high timer frequency */        getitimer(ITIMER_REAL, &itv);#if defined(__linux__)        /* XXX: force /dev/rtc usage because even 2.6 kernels may not           have timers with 1 ms resolution. The correct solution will           be to use the POSIX real time timers available in recent           2.6 kernels */        if (itv.it_interval.tv_usec > 1000 || 1) {            /* try to use /dev/rtc to have a faster timer */            if (start_rtc_timer() < 0)                goto use_itimer;            /* disable itimer */            itv.it_interval.tv_sec = 0;            itv.it_interval.tv_usec = 0;            itv.it_value.tv_sec = 0;            itv.it_value.tv_usec = 0;            setitimer(ITIMER_REAL, &itv, NULL);            /* use the RTC */            sigaction(SIGIO, &act, NULL);            fcntl(rtc_fd, F_SETFL, O_ASYNC);            fcntl(rtc_fd, F_SETOWN, getpid());        } else #endif /* defined(__linux__) */        {        use_itimer:            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *                                    PIT_FREQ) / 1000000;        }    }#endif}void quit_timers(void){#ifdef _WIN32    timeKillEvent(timerID);    timeEndPeriod(period);    if (host_alarm) {        CloseHandle(host_alarm);        host_alarm = NULL;    }#endif}/***********************************************************//* character device */static void qemu_chr_event(CharDriverState *s, int event){    if (!s->chr_event)        return;    s->chr_event(s->handler_opaque, event);}static void qemu_chr_reset_bh(void *opaque){    CharDriverState *s = opaque;    qemu_chr_event(s, CHR_EVENT_RESET);    qemu_bh_delete(s->bh);    s->bh = NULL;}void qemu_chr_reset(CharDriverState *s){    if (s->bh == NULL) {	s->bh = qemu_bh_new(qemu_chr_reset_bh, s);	qemu_bh_schedule(s->bh);    }}int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len){    return s->chr_write(s, buf, len);}int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg){    if (!s->chr_ioctl)        return -ENOTSUP;    return s->chr_ioctl(s, cmd, arg);}int qemu_chr_can_read(CharDriverState *s){    if (!s->chr_can_read)        return 0;    return s->chr_can_read(s->handler_opaque);}void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len){    s->chr_read(s->handler_opaque, buf, len);}void qemu_chr_printf(CharDriverState *s, const char *fmt, ...){    char buf[4096];    va_list ap;    va_start(ap, fmt);    vsnprintf(buf, sizeof(buf), fmt, ap);    qemu_chr_write(s, buf, strlen(buf));    va_end(ap);}void qemu_chr_send_event(CharDriverState *s, int event){    if (s->chr_send_event)        s->chr_send_event(s, event);}void qemu_chr_add_handlers(CharDriverState *s,                            IOCanRWHandler *fd_can_read,                            IOReadHandler *fd_read,                           IOEventHandler *fd_event,                           void *opaque){    s->chr_can_read = fd_can_read;    s->chr_read = fd_read;    s->chr_event = fd_event;    s->handler_opaque = opaque;    if (s->chr_update_read_handler)        s->chr_update_read_handler(s);}             static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    return len;}static CharDriverState *qemu_chr_open_null(void){    CharDriverState *chr;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    chr->chr_write = null_chr_write;    return chr;}#ifdef _WIN32static void socket_cleanup(void){    WSACleanup();}static int socket_init(void){    WSADATA Data;    int ret, err;    ret = WSAStartup(MAKEWORD(2,2), &Data);    if (ret != 0) {        err = WSAGetLastError();        fprintf(stderr, "WSAStartup: %d\n", err);        return -1;    }    atexit(socket_cleanup);    return 0;}static int send_all(int fd, const uint8_t *buf, int len1){    int ret, len;        len = len1;    while (len > 0) {        ret = send(fd, buf, len, 0);        if (ret < 0) {            int errno;            errno = WSAGetLastError();            if (errno != WSAEWOULDBLOCK) {                return -1;            }        } else if (ret == 0) {            break;        } else {            buf += ret;            len -= ret;        }    }    return len1 - len;}void socket_set_nonblock(int fd){    unsigned long opt = 1;    ioctlsocket(fd, FIONBIO, &opt);}#elsestatic int unix_write(int fd, const uint8_t *buf, int len1){    int ret, len;    len = len1;    while (len > 0) {        ret = write(fd, buf, len);        if (ret < 0) {            if (errno != EINTR && errno != EAGAIN)                return -1;        } else if (ret == 0) {            break;        } else {            buf += ret;            len -= ret;        }    }    return len1 - len;}static inline int send_all(int fd, const uint8_t *buf, int len1){    return unix_write(fd, buf, len1);}void socket_set_nonblock(int fd){    fcntl(fd, F_SETFL, O_NONBLOCK);}#endif /* !_WIN32 */#ifndef _WIN32typedef struct {    int fd_in, fd_out;    int max_size;} FDCharDriver;#define STDIO_MAX_CLIENTS 2static int stdio_nb_clients;static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    FDCharDriver *s = chr->opaque;    return unix_write(s->fd_out, buf, len);}static int fd_chr_read_poll(void *opaque){    CharDriverState *chr = opaque;    FDCharDriver *s = chr->opaque;    s->max_size = qemu_chr_can_read(chr);    return s->max_size;}static void fd_chr_read(void *opaque){    CharDriverState *chr = opaque;    FDCharDriver *s = chr->opaque;    int size, len;    uint8_t buf[1024];        len = sizeof(buf);    if (len > s->max_size)        len = s->max_size;    if (len == 0)        return;    size = read(s->fd_in, buf, len);    if (size == 0) {        /* FD has been closed. Remove it from the active list.  */        qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);        return;    }    if (size > 0) {        qemu_chr_read(chr, buf, size);    }}static void fd_chr_update_read_handler(CharDriverState *chr){    FDCharDriver *s = chr->opaque;    if (s->fd_in >= 0) {        if (nographic && s->fd_in == 0) {        } else {            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,                                  fd_chr_read, NULL, chr);        }    }}/* open a character device to a unix fd */static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out){    CharDriverState *chr;    FDCharDriver *s;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    s = qemu_mallocz(sizeof(FDCharDriver));    if (!s) {        free(chr);        return NULL;    }    s->fd_in = fd_in;    s->fd_out = fd_out;    chr->opaque = s;    chr->chr_write = fd_chr_write;    chr->chr_update_read_handler = fd_chr_update_read_handler;    qemu_chr_reset(chr);    return chr;}static CharDriverState *qemu_chr_open_file_out(const char *file_out){    int fd_out;    fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);    if (fd_out < 0)        return NULL;    return qemu_chr_open_fd(-1, fd_out);}static CharDriverState *qemu_chr_open_pipe(const char *filename){    int fd_in, fd_out;    char filename_in[256], filename_out[256];    snprintf(filename_in, 256, "%s.in", filename);    snprintf(filename_out, 256, "%s.out", filename);    fd_in = open(filename_in, O_RDWR | O_BINARY);    fd_out = open(filename_out, O_RDWR | O_BINARY);    if (fd_in < 0 || fd_out < 0) {	if (fd_in >= 0)	    close(fd_in);	if (fd_out >= 0)	    close(fd_out);        fd_in = fd_out = open(filename, O_RDWR | O_BINARY);        if (fd_in < 0)            return NULL;    }    return qemu_chr_open_fd(fd_in, fd_out);}/* for STDIO, we handle the case where several clients use it   (nographic mode) */#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */#define TERM_FIFO_MAX_SIZE 1static int term_got_escape, client_index;static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];static int term_fifo_size;static int term_timestamps;static int64_t term_timestamps_start;void term_print_help(void){    printf("\n"           "C-a h    print this help\n"           "C-a x    exit emulator\n"           "C-a s    save disk data back to file (if -snapshot)\n"           "C-a b    send break (magic sysrq)\n"           "C-a t    toggle console timestamps\n"           "C-a c    switch between console and monitor\n"           "C-a C-a  send C-a\n"           );}/* called when a char is received */static void stdio_received_byte(int ch){    if (term_got_escape) {        term_got_escape = 0;        switch(ch) {        case 'h':            term_print_help();            break;        case 'x':            exit(0);            break;        case 's':             {                int i;                for (i = 0; i < MAX_DISKS; i++) {                    if (bs_table[i])                        bdrv_commit(bs_table[i]);                }            }            break;        case 'b':            if (client_index < stdio_nb_clients) {                CharDriverState *chr;                FDCharDriver *s;                chr = stdio_clients[client_index];                s = chr->opaque;                qemu_chr_event(chr, CHR_EVENT_BREAK);            }            break;        case 'c':            client_index++;            if (client_index >= stdio_nb_clients)                client_index = 0;            if (client_index == 0) {                /* send a new line in the monitor to get the prompt */                ch = '\r';                goto send_char;            }            break;        case 't':            term_timestamps = !term_timestamps;            term_timestamps_start = -1;            break;        case TERM_ESCAPE:            goto send_char;        }    } else if (ch == TERM_ESCAPE) {        term_got_escape = 1;    } else {    send_char:        if (client_index < stdio_nb_clients) {            uint8_t buf[1];            CharDriverState *chr;                        chr = stdio_clients[client_index];            if (qemu_chr_can_read(chr) > 0) {                buf[0] = ch;                qemu_chr_read(chr, buf, 1);            } else if (term_fifo_size == 0) {                term_fifo[term_fifo_size++] = ch;            }        }    }}static int stdio_read_poll(void *opaque){    CharDriverState *chr;    if (client_index < stdio_nb_clients) {        chr = stdio_clients[client_index];        /* try to flush the queue if needed */        if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {            qemu_chr_read(chr, term_fifo, 1);            term_fifo_size = 0;        }        /* see if we can absorb more chars */        if (term_fifo_size == 0)            return 1;        else            return 0;    } else {        return 1;    }}static void stdio_read(void *opaque){    int size;    uint8_t buf[1];        size = read(0, buf, 1);    if (size == 0) {        /* stdin has been closed. Remove it from the active list.  */        qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);        return;    }    if (size > 0)        stdio_received_byte(buf[0]);}static int stdio_write(CharDriverState *chr, const uint8_t *buf, int len){    FDCharDriver *s = chr->opaque;    if (!term_timestamps) {        return unix_write(s->fd_out, buf, len);    } else {        int i;        char buf1[64];        for(i = 0; i < len; i++) {            unix_write(s->fd_out, buf + i, 1);            if (buf[i] == '\n') {                int64_t ti;                int secs;                ti = get_clock();                if (term_timestamps_start == -1)                    term_timestamps_start = ti;                ti -= term_timestamps_start;                secs = ti / 1000000000;                snprintf(buf1, sizeof(buf1),                          "[%02d:%02d:%02d.%03d] ",                         secs / 3600,                         (secs / 60) % 60,                         secs % 60,                         (int)((ti / 1000000) % 1000));                unix_write(s->fd_out, buf1, strlen(buf1));            }        }        return len;    }}/* init terminal so that we can grab keys */static struct termios oldtty;static int old_fd0_flags;static void term_exit(void){    tcsetattr (0, TCSANOW, &oldtty);    fcntl(0, F_SETFL, old_fd0_flags);}static void term_init(void){    struct termios tty;    tcgetattr (0, &tty);    oldtty = tty;    old_fd0_flags = fcntl(0, F_GETFL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -