void wait_for_event(struct state *state) { s64 event_usecs = script_time_to_live_time_usecs( state, state->event->time_usecs); DEBUGP("waiting until %lld -- now is %lld\n", event_usecs, now_usecs()); while (1) { const s64 wait_usecs = event_usecs - now_usecs(); if (wait_usecs <= 0) break; /* If we're waiting a long time, and we are on an OS * that we know has a fine-grained usleep(), then * usleep() instead of spinning on the CPU. */ #ifdef linux /* Since the scheduler may not wake us up precisely * when we tell it to, sleep until just before the * event we're waiting for and then spin. */ if (wait_usecs > MAX_SPIN_USECS) { run_unlock(state); usleep(wait_usecs - MAX_SPIN_USECS); run_lock(state); } #endif /* At this point we should only have a millisecond or * two to wait, so we spin. */ } check_event_time(state, now_usecs()); }
void button_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) { if (!antares_is_active()) { return; } bool down = IOHIDValueGetIntegerValue(value); uint16_t usage = IOHIDElementGetUsage(element); if (down) { enqueue(new GamepadButtonDownEvent(now_usecs(), usage)); } else { enqueue(new GamepadButtonUpEvent(now_usecs(), usage)); } }
void analog_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) { int int_value = IOHIDValueGetIntegerValue(value); uint16_t usage = IOHIDElementGetUsage(element); switch (usage) { case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: { int min = IOHIDElementGetLogicalMin(element); int max = IOHIDElementGetLogicalMax(element); double double_value = int_value; if (int_value < 0) { double_value = -(double_value / min); } else { double_value = (double_value / max); } usage -= kHIDUsage_GD_X; gamepad[usage] = double_value; static const int x_component[] = {0, 0, -1, 3, 3, -1}; double x = gamepad[x_component[usage]]; double y = gamepad[x_component[usage] + 1]; enqueue(new GamepadStickEvent( now_usecs(), kHIDUsage_GD_X + x_component[usage], x, y)); } break; case kHIDUsage_GD_Z: case kHIDUsage_GD_Rz: button_event(result, element, value); break; } }
/* Execute the server-side duties for remote on-the-wire testing using * a real NIC. Basically the server side just needs to send packets * over the wire (to the kernel under test) and sniff and verify * packets on the wire (from the kernel under test). This is analogous * to run_script(), which executes scripts for stand-alone mode, * and also executes the client side for remote on-the-wire testing * using a real NIC. */ static int wire_server_run_script(struct wire_server *wire_server, char **error) { struct state *state = wire_server->state; struct event *event = NULL; DEBUGP("wire_server_run_script\n"); state->live_start_time_usecs = now_usecs(); DEBUGP("live_start_time_usecs is %lld\n", state->live_start_time_usecs); while (1) { if (get_next_event(state, error)) return STATUS_ERR; event = state->event; if (event == NULL) break; if (wire_server_next_event(wire_server, event)) return STATUS_ERR; /* We adjust relative times after getting notification * that previous client-side events have completed. */ adjust_relative_event_times(state, event); switch (event->type) { case PACKET_EVENT: if (wire_server_run_packet_event(wire_server, event, event->event.packet, error) == STATUS_ERR) return STATUS_ERR; break; case SYSCALL_EVENT: DEBUGP("SYSCALL_EVENT happens on client side...\n"); break; case COMMAND_EVENT: DEBUGP("COMMAND_EVENT happens on client side...\n"); break; case CODE_EVENT: DEBUGP("CODE_EVENT happens on client side...\n"); break; case INVALID_EVENT: case NUM_EVENT_TYPES: assert(!"bogus type"); break; /* We omit default case so compiler catches missing values. */ } } /* Tell the client about any outstanding packet events it requested. */ wire_server_next_event(wire_server, NULL); DEBUGP("wire_server_run_script: done running\n"); return STATUS_OK; }
void key_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) { if (!antares_is_active()) { return; } bool down = IOHIDValueGetIntegerValue(value); uint16_t scan_code = IOHIDElementGetUsage(element); if ((scan_code < 4) || (231 < scan_code)) { return; } else if (scan_code == Keys::CAPS_LOCK) { return; } if (down) { enqueue(new KeyDownEvent(now_usecs(), scan_code)); } else { enqueue(new KeyUpEvent(now_usecs(), scan_code)); } }
void ScrollTextScreen::fire_timer() { int64_t now = now_usecs(); while (_next_shift < now) { _next_shift += (1e6 / _speed); _position.offset(0, -1); } if (!_position.intersects(_clip)) { stack()->pop(this); } }
/* Wait for and return the wall time at which we should start the * test, in microseconds. To make test results more reproducible, we * wait for a start time that is well into the middle of a Linux jiffy * (JIFFY_OFFSET_USECS into the jiffy). If you try to run a test * script starting at a time that is too near the edge of a jiffy, and * the test tries (as most do) to schedule events at 1-millisecond * boundaries relative to this start time, then slight CPU or * scheduling variations cause the kernel to record time measurements * that are 1 jiffy too big or too small, so the kernel gets * unexpected RTT and RTT variance values, leading to unexpected RTO * and delayed ACK timer behavior. * * To try to find the edge of a jiffy, we spin and watch the output of * times(2), which increments every time the jiffies clock has * advanced another 10ms. We wait for a few ticks * (TARGET_JIFFY_TICKS) to go by, to reduce noise from warm-up * effects. We could do fancier measuring and filtering here, but so * far this level of complexity seems sufficient. */ static s64 schedule_start_time_usecs(void) { #ifdef linux s64 start_usecs = 0; clock_t last_jiffies = times(NULL); int jiffy_ticks = 0; const int TARGET_JIFFY_TICKS = 10; while (jiffy_ticks < TARGET_JIFFY_TICKS) { clock_t jiffies = times(NULL); if (jiffies != last_jiffies) { start_usecs = now_usecs(); ++jiffy_ticks; } last_jiffies = jiffies; } const int JIFFY_OFFSET_USECS = 250; start_usecs += JIFFY_OFFSET_USECS; return start_usecs; #else return now_usecs(); #endif }
int get_next_event(struct state *state, char **error) { DEBUGP("gettimeofday: %.6f\n", now_usecs()/1000000.0); if (state->event == NULL) { /* First event. */ state->event = state->script->event_list; state->script_start_time_usecs = state->event->time_usecs; if (state->event->time_usecs != 0) { asprintf(error, "%s:%d: first event should be at time 0\n", state->config->script_path, state->event->line_number); return STATUS_ERR; } } else { /* Move to the next event. */ state->script_last_time_usecs = state->event->time_usecs; state->last_event = state->event; state->event = state->event->next; } if (state->event == NULL) return STATUS_OK; /* script is done */ assert((state->event->type > INVALID_EVENT) && (state->event->type < NUM_EVENT_TYPES)); if (state->last_event && is_event_time_absolute(state->last_event) && is_event_time_absolute(state->event) && state->event->time_usecs < state->script_last_time_usecs) { asprintf(error, "%s:%d: time goes backward in script " "from %lld usec to %lld usec\n", state->config->script_path, state->event->line_number, state->script_last_time_usecs, state->event->time_usecs); return STATUS_ERR; } return STATUS_OK; }
void ScrollTextScreen::become_front() { // If a song was requested, play it. if (_play_song && Preferences::preferences()->play_idle_music()) { if (SongIsPlaying()) { StopAndUnloadSong(); } LoadSong(_song_id); SetSongVolume(kMaxMusicVolume); PlaySong(); } _start = now_usecs(); _next_shift = _start; _clip = Rect(0, 0, world.width(), kScrollTextHeight); _clip.center_in(world); _position = _build_pix.size().as_rect(); _position.center_in(_clip); _position.offset(0, _clip.bottom - _position.top); }
/* Set the start (and end time, if applicable) for the event if it * uses wildcard or relative timing. */ void adjust_relative_event_times(struct state *state, struct event *event) { s64 offset_usecs; if (event->time_type != ANY_TIME && event->time_type != RELATIVE_TIME && event->time_type != RELATIVE_RANGE_TIME) return; offset_usecs = now_usecs() - state->live_start_time_usecs; event->offset_usecs = offset_usecs; event->time_usecs += offset_usecs; if (event->time_type == RELATIVE_RANGE_TIME) event->time_usecs_end += offset_usecs; /* Adjust the end time of blocking system calls using relative times. */ if (event->time_type == RELATIVE_TIME && event->type == SYSCALL_EVENT && is_blocking_syscall(event->event.syscall)) { event->event.syscall->end_usecs += offset_usecs; } }
static void caps_unlock(void* userdata) { EventBridge* self = reinterpret_cast<EventBridge*>(userdata); self->enqueue(new KeyUpEvent(now_usecs(), Keys::CAPS_LOCK)); }
static void mouse_move(int32_t x, int32_t y, void* userdata) { EventBridge* self = reinterpret_cast<EventBridge*>(userdata); self->enqueue(new MouseMoveEvent(now_usecs(), Point(x, y))); }
static void mouse_up(int button, int32_t x, int32_t y, void* userdata) { EventBridge* self = reinterpret_cast<EventBridge*>(userdata); self->enqueue(new MouseUpEvent(now_usecs(), button, Point(x, y))); }