mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2025-01-22 08:11:47 -05:00
use memory arena to optimize handing data to frontend
This commit is contained in:
parent
410b002d99
commit
242386ea75
6 changed files with 103 additions and 15 deletions
|
@ -30,6 +30,8 @@ void Backend::vanillaEventHandler()
|
||||||
emit vibrate(*event.data);
|
emit vibrate(*event.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vanilla_free_event(&event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "gamepad.h"
|
#include "gamepad.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
@ -31,18 +32,21 @@ uint16_t PORT_AUD;
|
||||||
uint16_t PORT_HID;
|
uint16_t PORT_HID;
|
||||||
uint16_t PORT_CMD;
|
uint16_t PORT_CMD;
|
||||||
|
|
||||||
|
#define EVENT_BUFFER_SIZE 65536
|
||||||
|
#define EVENT_BUFFER_ARENA_SIZE VANILLA_MAX_EVENT_COUNT * 2
|
||||||
|
uint8_t *EVENT_BUFFER_ARENA[EVENT_BUFFER_ARENA_SIZE] = {0};
|
||||||
|
|
||||||
void send_to_console(int fd, const void *data, size_t data_size, int port)
|
void send_to_console(int fd, const void *data, size_t data_size, int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
address.sin_family = AF_INET;
|
address.sin_family = AF_INET;
|
||||||
address.sin_addr.s_addr = SERVER_ADDRESS;
|
address.sin_addr.s_addr = SERVER_ADDRESS;
|
||||||
address.sin_port = htons((uint16_t) (port - 100));
|
address.sin_port = htons((uint16_t) (port - 100));
|
||||||
|
|
||||||
char ip[INET_ADDRSTRLEN];
|
|
||||||
inet_ntop(AF_INET, &address.sin_addr, ip, INET_ADDRSTRLEN);
|
|
||||||
|
|
||||||
ssize_t sent = sendto(fd, data, data_size, 0, (const struct sockaddr *) &address, sizeof(address));
|
ssize_t sent = sendto(fd, data, data_size, 0, (const struct sockaddr *) &address, sizeof(address));
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
|
char ip[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &address.sin_addr, ip, INET_ADDRSTRLEN);
|
||||||
print_info("Failed to send to Wii U socket: address: %s, fd: %d, port: %d, errno: %i", ip, fd, port - 100, errno);
|
print_info("Failed to send to Wii U socket: address: %s, fd: %d, port: %d, errno: %i", ip, fd, port - 100, errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,12 +290,19 @@ int is_stop_code(const char *data, size_t data_length)
|
||||||
|
|
||||||
int push_event(event_loop_t *loop, int type, const void *data, size_t size)
|
int push_event(event_loop_t *loop, int type, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
pthread_mutex_lock(&loop->mutex);
|
pthread_mutex_lock(&loop->mutex);
|
||||||
|
|
||||||
vanilla_event_t *ev = &loop->events[loop->new_index % VANILLA_MAX_EVENT_COUNT];
|
vanilla_event_t *ev = &loop->events[loop->new_index % VANILLA_MAX_EVENT_COUNT];
|
||||||
|
|
||||||
if (size <= sizeof(ev->data)) {
|
if (size <= EVENT_BUFFER_SIZE) {
|
||||||
|
assert(!ev->data);
|
||||||
|
|
||||||
|
ev->data = get_event_buffer();
|
||||||
|
if (!ev->data) {
|
||||||
|
print_info("OUT OF MEMORY FOR NEW EVENTS");
|
||||||
|
return VANILLA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ev->type = type;
|
ev->type = type;
|
||||||
memcpy(ev->data, data, size);
|
memcpy(ev->data, data, size);
|
||||||
ev->size = size;
|
ev->size = size;
|
||||||
|
@ -300,13 +311,14 @@ int push_event(event_loop_t *loop, int type, const void *data, size_t size)
|
||||||
|
|
||||||
// Prevent rollover by skipping oldest event if necessary
|
// Prevent rollover by skipping oldest event if necessary
|
||||||
if (loop->new_index > loop->used_index + VANILLA_MAX_EVENT_COUNT) {
|
if (loop->new_index > loop->used_index + VANILLA_MAX_EVENT_COUNT) {
|
||||||
|
vanilla_free_event(&loop->events[loop->used_index % VANILLA_MAX_EVENT_COUNT]);
|
||||||
print_info("SKIPPED EVENT TO PREVENT ROLLOVER (%lu > %lu + %lu)", loop->new_index, loop->used_index, VANILLA_MAX_EVENT_COUNT);
|
print_info("SKIPPED EVENT TO PREVENT ROLLOVER (%lu > %lu + %lu)", loop->new_index, loop->used_index, VANILLA_MAX_EVENT_COUNT);
|
||||||
loop->used_index++;
|
loop->used_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_cond_broadcast(&loop->waitcond);
|
pthread_cond_broadcast(&loop->waitcond);
|
||||||
} else {
|
} else {
|
||||||
print_info("FAILED TO PUSH EVENT: wanted %lu, only had %lu. This is a bug, please report to developers.\n", size, sizeof(ev->data));
|
print_info("FAILED TO PUSH EVENT: wanted %lu, only had %lu. This is a bug, please report to developers.\n", size, EVENT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&loop->mutex);
|
pthread_mutex_unlock(&loop->mutex);
|
||||||
|
@ -330,9 +342,11 @@ int get_event(event_loop_t *loop, vanilla_event_t *event, int wait)
|
||||||
vanilla_event_t *pull_event = &loop->events[loop->used_index % VANILLA_MAX_EVENT_COUNT];
|
vanilla_event_t *pull_event = &loop->events[loop->used_index % VANILLA_MAX_EVENT_COUNT];
|
||||||
|
|
||||||
event->type = pull_event->type;
|
event->type = pull_event->type;
|
||||||
memcpy(event->data, pull_event->data, pull_event->size);
|
event->data = pull_event->data;
|
||||||
event->size = pull_event->size;
|
event->size = pull_event->size;
|
||||||
|
|
||||||
|
pull_event->data = NULL;
|
||||||
|
|
||||||
loop->used_index++;
|
loop->used_index++;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
@ -341,4 +355,52 @@ int get_event(event_loop_t *loop, vanilla_event_t *event, int wait)
|
||||||
pthread_mutex_unlock(&loop->mutex);
|
pthread_mutex_unlock(&loop->mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *get_event_buffer()
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < EVENT_BUFFER_ARENA_SIZE; i++) {
|
||||||
|
if (EVENT_BUFFER_ARENA[i]) {
|
||||||
|
buf = EVENT_BUFFER_ARENA[i];
|
||||||
|
EVENT_BUFFER_ARENA[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_event_buffer(void *buffer)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < EVENT_BUFFER_ARENA_SIZE; i++) {
|
||||||
|
if (!EVENT_BUFFER_ARENA[i]) {
|
||||||
|
EVENT_BUFFER_ARENA[i] = buffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_event_buffer_arena()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < EVENT_BUFFER_ARENA_SIZE; i++) {
|
||||||
|
if (!EVENT_BUFFER_ARENA[i]) {
|
||||||
|
EVENT_BUFFER_ARENA[i] = malloc(EVENT_BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
print_info("CRITICAL: Buffer wasn't returned to the arena");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_event_buffer_arena()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < EVENT_BUFFER_ARENA_SIZE; i++) {
|
||||||
|
if (EVENT_BUFFER_ARENA[i]) {
|
||||||
|
free(EVENT_BUFFER_ARENA[i]);
|
||||||
|
EVENT_BUFFER_ARENA[i] = NULL;
|
||||||
|
} else {
|
||||||
|
print_info("CRITICAL: Buffer wasn't returned to the arena");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -42,4 +42,9 @@ int is_stop_code(const char *data, size_t data_length);
|
||||||
int push_event(event_loop_t *loop, int type, const void *data, size_t size);
|
int push_event(event_loop_t *loop, int type, const void *data, size_t size);
|
||||||
int get_event(event_loop_t *loop, vanilla_event_t *event, int wait);
|
int get_event(event_loop_t *loop, vanilla_event_t *event, int wait);
|
||||||
|
|
||||||
|
void init_event_buffer_arena();
|
||||||
|
void free_event_buffer_arena();
|
||||||
|
void *get_event_buffer();
|
||||||
|
void release_event_buffer(void *buffer);
|
||||||
|
|
||||||
#endif // VANILLA_GAMEPAD_H
|
#endif // VANILLA_GAMEPAD_H
|
|
@ -30,9 +30,13 @@ void *start_gamepad(void *arg)
|
||||||
struct gamepad_data_t *data = (struct gamepad_data_t *) arg;
|
struct gamepad_data_t *data = (struct gamepad_data_t *) arg;
|
||||||
|
|
||||||
pthread_mutex_lock(&event_loop.mutex);
|
pthread_mutex_lock(&event_loop.mutex);
|
||||||
|
init_event_buffer_arena();
|
||||||
event_loop.active = 1;
|
event_loop.active = 1;
|
||||||
event_loop.new_index = 0;
|
event_loop.new_index = 0;
|
||||||
event_loop.used_index = 0;
|
event_loop.used_index = 0;
|
||||||
|
for (int i = 0; i < VANILLA_MAX_EVENT_COUNT; i++) {
|
||||||
|
event_loop.events[i].data = NULL;
|
||||||
|
}
|
||||||
pthread_cond_broadcast(&event_loop.waitcond);
|
pthread_cond_broadcast(&event_loop.waitcond);
|
||||||
pthread_mutex_unlock(&event_loop.mutex);
|
pthread_mutex_unlock(&event_loop.mutex);
|
||||||
|
|
||||||
|
@ -42,6 +46,7 @@ void *start_gamepad(void *arg)
|
||||||
|
|
||||||
pthread_mutex_lock(&event_loop.mutex);
|
pthread_mutex_lock(&event_loop.mutex);
|
||||||
event_loop.active = 0;
|
event_loop.active = 0;
|
||||||
|
free_event_buffer_arena();
|
||||||
pthread_cond_broadcast(&event_loop.waitcond);
|
pthread_cond_broadcast(&event_loop.waitcond);
|
||||||
pthread_mutex_unlock(&event_loop.mutex);
|
pthread_mutex_unlock(&event_loop.mutex);
|
||||||
|
|
||||||
|
@ -170,4 +175,12 @@ int vanilla_poll_event(vanilla_event_t *event)
|
||||||
int vanilla_wait_event(vanilla_event_t *event)
|
int vanilla_wait_event(vanilla_event_t *event)
|
||||||
{
|
{
|
||||||
return get_event(&event_loop, event, 1);
|
return get_event(&event_loop, event, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vanilla_free_event(vanilla_event_t *event)
|
||||||
|
{
|
||||||
|
if (event->data) {
|
||||||
|
release_event_buffer(event->data);
|
||||||
|
event->data = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -98,7 +98,7 @@ static const uint8_t VANILLA_PPS_PARAMS[] = {
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
uint8_t data[65536];
|
uint8_t *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
} vanilla_event_t;
|
} vanilla_event_t;
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ int vanilla_sync(uint16_t code, uint32_t server_address);
|
||||||
|
|
||||||
int vanilla_poll_event(vanilla_event_t *event);
|
int vanilla_poll_event(vanilla_event_t *event);
|
||||||
int vanilla_wait_event(vanilla_event_t *event);
|
int vanilla_wait_event(vanilla_event_t *event);
|
||||||
|
int vanilla_free_event(vanilla_event_t *event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to stop the current action
|
* Attempt to stop the current action
|
||||||
|
|
19
rpi/main.c
19
rpi/main.c
|
@ -105,23 +105,25 @@ static SDL_mutex *decode_loop_mutex;
|
||||||
static SDL_cond *decode_loop_cond;
|
static SDL_cond *decode_loop_cond;
|
||||||
static int decode_loop_running = 0;
|
static int decode_loop_running = 0;
|
||||||
static int decode_pkt_ready = 0;
|
static int decode_pkt_ready = 0;
|
||||||
static vanilla_event_t decode_event;
|
static uint8_t decode_data[65536];
|
||||||
|
static size_t decode_size = 0;
|
||||||
int decode_loop(void *)
|
int decode_loop(void *)
|
||||||
{
|
{
|
||||||
vanilla_event_t our_pkt;
|
uint8_t our_data[65536];
|
||||||
|
size_t our_data_size = 0;
|
||||||
|
|
||||||
SDL_LockMutex(decode_loop_mutex);
|
SDL_LockMutex(decode_loop_mutex);
|
||||||
while (decode_loop_running) {
|
while (decode_loop_running) {
|
||||||
while (!decode_pkt_ready) {
|
while (!decode_pkt_ready) {
|
||||||
SDL_CondWait(decode_loop_cond, decode_loop_mutex);
|
SDL_CondWait(decode_loop_cond, decode_loop_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
our_pkt = decode_event;
|
memcpy(our_data, decode_data, decode_size);
|
||||||
decode_pkt_ready = 0;
|
our_data_size = decode_size;
|
||||||
|
|
||||||
SDL_UnlockMutex(decode_loop_mutex);
|
SDL_UnlockMutex(decode_loop_mutex);
|
||||||
|
|
||||||
decode(our_pkt.data, our_pkt.size);
|
decode(our_data, decode_size);
|
||||||
|
|
||||||
SDL_LockMutex(decode_loop_mutex);
|
SDL_LockMutex(decode_loop_mutex);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,8 @@ int run_backend(void *data)
|
||||||
while (vanilla_wait_event(&event)) {
|
while (vanilla_wait_event(&event)) {
|
||||||
if (event.type == VANILLA_EVENT_VIDEO) {
|
if (event.type == VANILLA_EVENT_VIDEO) {
|
||||||
SDL_LockMutex(decode_loop_mutex);
|
SDL_LockMutex(decode_loop_mutex);
|
||||||
decode_event = event;
|
memcpy(decode_data, event.data, event.size);
|
||||||
|
decode_size = event.size;
|
||||||
decode_pkt_ready = 1;
|
decode_pkt_ready = 1;
|
||||||
SDL_CondBroadcast(decode_loop_cond);
|
SDL_CondBroadcast(decode_loop_cond);
|
||||||
SDL_UnlockMutex(decode_loop_mutex);
|
SDL_UnlockMutex(decode_loop_mutex);
|
||||||
|
@ -167,6 +170,8 @@ int run_backend(void *data)
|
||||||
} else if (event.type == VANILLA_EVENT_VIBRATE) {
|
} else if (event.type == VANILLA_EVENT_VIBRATE) {
|
||||||
vibrate = event.data[0];
|
vibrate = event.data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vanilla_free_event(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockMutex(decode_loop_mutex);
|
SDL_LockMutex(decode_loop_mutex);
|
||||||
|
|
Loading…
Reference in a new issue