Пример #1
0
void replay_char_write_event_load(int *res, int *offset)
{
    replay_account_executed_instructions();
    replay_mutex_lock();
    if (replay_next_event_is(EVENT_CHAR_WRITE)) {
        *res = replay_get_dword();
        *offset = replay_get_dword();
        replay_finish_event();
        replay_mutex_unlock();
    } else {
        replay_mutex_unlock();
        error_report("Missing character write event in the replay log");
        exit(1);
    }
}
Пример #2
0
bool replay_checkpoint(ReplayCheckpoint checkpoint)
{
    bool res = false;
    assert(EVENT_CHECKPOINT + checkpoint <= EVENT_CHECKPOINT_LAST);
    replay_save_instructions();

    if (!replay_file) {
        return true;
    }

    replay_mutex_lock();

    if (replay_mode == REPLAY_MODE_PLAY) {
        if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {
            replay_finish_event();
        } else if (replay_state.data_kind != EVENT_ASYNC) {
            res = false;
            goto out;
        }
        replay_read_events(checkpoint);
        /* replay_read_events may leave some unread events.
           Return false if not all of the events associated with
           checkpoint were processed */
        res = replay_state.data_kind != EVENT_ASYNC;
    } else if (replay_mode == REPLAY_MODE_RECORD) {
        replay_put_event(EVENT_CHECKPOINT + checkpoint);
        replay_save_events(checkpoint);
        res = true;
    }
out:
    replay_mutex_unlock();
    return res;
}
Пример #3
0
void replay_char_read_all_save_buf(uint8_t *buf, int offset)
{
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_READ_ALL);
    replay_put_array(buf, offset);
    replay_mutex_unlock();
}
Пример #4
0
void replay_shutdown_request(void)
{
    if (replay_mode == REPLAY_MODE_RECORD) {
        replay_mutex_lock();
        replay_put_event(EVENT_SHUTDOWN);
        replay_mutex_unlock();
    }
}
Пример #5
0
void replay_char_read_all_save_error(int res)
{
    assert(res < 0);
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_READ_ALL_ERROR);
    replay_put_dword(res);
    replay_mutex_unlock();
}
Пример #6
0
void replay_char_write_event_save(int res, int offset)
{
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_WRITE);
    replay_put_dword(res);
    replay_put_dword(offset);
    replay_mutex_unlock();
}
Пример #7
0
int replay_get_instructions(void)
{
    int res = 0;
    replay_mutex_lock();
    if (replay_next_event_is(EVENT_INSTRUCTION)) {
        res = replay_state.instructions_count;
    }
    replay_mutex_unlock();
    return res;
}
Пример #8
0
bool replay_exception(void)
{
    if (replay_mode == REPLAY_MODE_RECORD) {
        replay_save_instructions();
        replay_mutex_lock();
        replay_put_event(EVENT_EXCEPTION);
        replay_mutex_unlock();
        return true;
    } else if (replay_mode == REPLAY_MODE_PLAY) {
        bool res = replay_has_exception();
        if (res) {
            replay_mutex_lock();
            replay_finish_event();
            replay_mutex_unlock();
        }
        return res;
    }

    return true;
}
Пример #9
0
bool replay_has_interrupt(void)
{
    bool res = false;
    if (replay_mode == REPLAY_MODE_PLAY) {
        replay_account_executed_instructions();
        replay_mutex_lock();
        res = replay_next_event_is(EVENT_INTERRUPT);
        replay_mutex_unlock();
    }
    return res;
}
Пример #10
0
bool replay_interrupt(void)
{
    if (replay_mode == REPLAY_MODE_RECORD) {
        replay_save_instructions();
        replay_mutex_lock();
        replay_put_event(EVENT_INTERRUPT);
        replay_mutex_unlock();
        return true;
    } else if (replay_mode == REPLAY_MODE_PLAY) {
        bool res = replay_has_interrupt();
        if (res) {
            replay_mutex_lock();
            replay_finish_event();
            replay_mutex_unlock();
        }
        return res;
    }

    return true;
}
Пример #11
0
bool replay_has_exception(void)
{
    bool res = false;
    if (replay_mode == REPLAY_MODE_PLAY) {
        replay_account_executed_instructions();
        replay_mutex_lock();
        res = replay_next_event_is(EVENT_EXCEPTION);
        replay_mutex_unlock();
    }

    return res;
}
Пример #12
0
int replay_char_read_all_load(uint8_t *buf)
{
    replay_mutex_lock();
    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
        size_t size;
        int res;
        replay_get_array(buf, &size);
        replay_finish_event();
        replay_mutex_unlock();
        res = (int)size;
        assert(res >= 0);
        return res;
    } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) {
        int res = replay_get_dword();
        replay_finish_event();
        replay_mutex_unlock();
        return res;
    } else {
        replay_mutex_unlock();
        error_report("Missing character read all event in the replay log");
        exit(1);
    }
}
Пример #13
0
void replay_account_executed_instructions(void)
{
    if (replay_mode == REPLAY_MODE_PLAY) {
        replay_mutex_lock();
        if (replay_state.instructions_count > 0) {
            int count = (int)(replay_get_current_step()
                              - replay_state.current_step);
            replay_state.instructions_count -= count;
            replay_state.current_step += count;
            if (replay_state.instructions_count == 0) {
                assert(replay_state.data_kind == EVENT_INSTRUCTION);
                replay_finish_event();
                /* Wake up iothread. This is required because
                   timers will not expire until clock counters
                   will be read from the log. */
                qemu_notify_event();
            }
        }
        replay_mutex_unlock();
    }
}
Пример #14
0
static int os_host_main_loop_wait(int64_t timeout)
{
    GMainContext *context = g_main_context_default();
    int ret;

    g_main_context_acquire(context);

    glib_pollfds_fill(&timeout);

    qemu_mutex_unlock_iothread();
    replay_mutex_unlock();

    ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout);

    replay_mutex_lock();
    qemu_mutex_lock_iothread();

    glib_pollfds_poll();

    g_main_context_release(context);

    return ret;
}
Пример #15
0
static int os_host_main_loop_wait(int64_t timeout)
{
    GMainContext *context = g_main_context_default();
    GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
    int select_ret = 0;
    int g_poll_ret, ret, i, n_poll_fds;
    PollingEntry *pe;
    WaitObjects *w = &wait_objects;
    gint poll_timeout;
    int64_t poll_timeout_ns;
    static struct timeval tv0;
    fd_set rfds, wfds, xfds;
    int nfds;

    g_main_context_acquire(context);

    /* XXX: need to suppress polling by better using win32 events */
    ret = 0;
    for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
        ret |= pe->func(pe->opaque);
    }
    if (ret != 0) {
        g_main_context_release(context);
        return ret;
    }

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&xfds);
    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
    if (nfds >= 0) {
        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
        if (select_ret != 0) {
            timeout = 0;
        }
        if (select_ret > 0) {
            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
        }
    }

    g_main_context_prepare(context, &max_priority);
    n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
                                      poll_fds, ARRAY_SIZE(poll_fds));
    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));

    for (i = 0; i < w->num; i++) {
        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
        poll_fds[n_poll_fds + i].events = G_IO_IN;
    }

    if (poll_timeout < 0) {
        poll_timeout_ns = -1;
    } else {
        poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
    }

    poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);

    qemu_mutex_unlock_iothread();

    replay_mutex_unlock();

    g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);

    replay_mutex_lock();

    qemu_mutex_lock_iothread();
    if (g_poll_ret > 0) {
        for (i = 0; i < w->num; i++) {
            w->revents[i] = poll_fds[n_poll_fds + i].revents;
        }
        for (i = 0; i < w->num; i++) {
            if (w->revents[i] && w->func[i]) {
                w->func[i](w->opaque[i]);
            }
        }
    }

    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
        g_main_context_dispatch(context);
    }

    g_main_context_release(context);

    return select_ret || g_poll_ret;
}