Пример #1
0
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());
}
Пример #2
0
 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));
     }
 }
Пример #3
0
    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;
        }
    }
Пример #4
0
/* 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;
}
Пример #5
0
    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));
        }
    }
Пример #6
0
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);
    }
}
Пример #7
0
/* 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
}
Пример #8
0
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;
}
Пример #9
0
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);
}
Пример #10
0
/* 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;
	}
}
Пример #11
0
 static void caps_unlock(void* userdata) {
     EventBridge* self = reinterpret_cast<EventBridge*>(userdata);
     self->enqueue(new KeyUpEvent(now_usecs(), Keys::CAPS_LOCK));
 }
Пример #12
0
 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)));
 }
Пример #13
0
 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)));
 }