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);
|
||||
break;
|
||||
}
|
||||
|
||||
vanilla_free_event(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "gamepad.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
|
@ -31,6 +32,10 @@ uint16_t PORT_AUD;
|
|||
uint16_t PORT_HID;
|
||||
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)
|
||||
{
|
||||
struct sockaddr_in address;
|
||||
|
@ -38,11 +43,10 @@ void send_to_console(int fd, const void *data, size_t data_size, int port)
|
|||
address.sin_addr.s_addr = SERVER_ADDRESS;
|
||||
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));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&loop->mutex);
|
||||
|
||||
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;
|
||||
memcpy(ev->data, data, 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
|
||||
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);
|
||||
loop->used_index++;
|
||||
}
|
||||
|
||||
pthread_cond_broadcast(&loop->waitcond);
|
||||
} 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);
|
||||
|
@ -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];
|
||||
|
||||
event->type = pull_event->type;
|
||||
memcpy(event->data, pull_event->data, pull_event->size);
|
||||
event->data = pull_event->data;
|
||||
event->size = pull_event->size;
|
||||
|
||||
pull_event->data = NULL;
|
||||
|
||||
loop->used_index++;
|
||||
ret = 1;
|
||||
}
|
||||
|
@ -342,3 +356,51 @@ int get_event(event_loop_t *loop, vanilla_event_t *event, int wait)
|
|||
|
||||
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 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
|
|
@ -30,9 +30,13 @@ void *start_gamepad(void *arg)
|
|||
struct gamepad_data_t *data = (struct gamepad_data_t *) arg;
|
||||
|
||||
pthread_mutex_lock(&event_loop.mutex);
|
||||
init_event_buffer_arena();
|
||||
event_loop.active = 1;
|
||||
event_loop.new_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_mutex_unlock(&event_loop.mutex);
|
||||
|
||||
|
@ -42,6 +46,7 @@ void *start_gamepad(void *arg)
|
|||
|
||||
pthread_mutex_lock(&event_loop.mutex);
|
||||
event_loop.active = 0;
|
||||
free_event_buffer_arena();
|
||||
pthread_cond_broadcast(&event_loop.waitcond);
|
||||
pthread_mutex_unlock(&event_loop.mutex);
|
||||
|
||||
|
@ -171,3 +176,11 @@ int vanilla_wait_event(vanilla_event_t *event)
|
|||
{
|
||||
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
|
||||
{
|
||||
int type;
|
||||
uint8_t data[65536];
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
} 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_wait_event(vanilla_event_t *event);
|
||||
int vanilla_free_event(vanilla_event_t *event);
|
||||
|
||||
/**
|
||||
* Attempt to stop the current action
|
||||
|
|
17
rpi/main.c
17
rpi/main.c
|
@ -105,10 +105,12 @@ static SDL_mutex *decode_loop_mutex;
|
|||
static SDL_cond *decode_loop_cond;
|
||||
static int decode_loop_running = 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 *)
|
||||
{
|
||||
vanilla_event_t our_pkt;
|
||||
uint8_t our_data[65536];
|
||||
size_t our_data_size = 0;
|
||||
|
||||
SDL_LockMutex(decode_loop_mutex);
|
||||
while (decode_loop_running) {
|
||||
|
@ -116,12 +118,12 @@ int decode_loop(void *)
|
|||
SDL_CondWait(decode_loop_cond, decode_loop_mutex);
|
||||
}
|
||||
|
||||
our_pkt = decode_event;
|
||||
decode_pkt_ready = 0;
|
||||
memcpy(our_data, decode_data, decode_size);
|
||||
our_data_size = decode_size;
|
||||
|
||||
SDL_UnlockMutex(decode_loop_mutex);
|
||||
|
||||
decode(our_pkt.data, our_pkt.size);
|
||||
decode(our_data, decode_size);
|
||||
|
||||
SDL_LockMutex(decode_loop_mutex);
|
||||
}
|
||||
|
@ -153,7 +155,8 @@ int run_backend(void *data)
|
|||
while (vanilla_wait_event(&event)) {
|
||||
if (event.type == VANILLA_EVENT_VIDEO) {
|
||||
SDL_LockMutex(decode_loop_mutex);
|
||||
decode_event = event;
|
||||
memcpy(decode_data, event.data, event.size);
|
||||
decode_size = event.size;
|
||||
decode_pkt_ready = 1;
|
||||
SDL_CondBroadcast(decode_loop_cond);
|
||||
SDL_UnlockMutex(decode_loop_mutex);
|
||||
|
@ -167,6 +170,8 @@ int run_backend(void *data)
|
|||
} else if (event.type == VANILLA_EVENT_VIBRATE) {
|
||||
vibrate = event.data[0];
|
||||
}
|
||||
|
||||
vanilla_free_event(&event);
|
||||
}
|
||||
|
||||
SDL_LockMutex(decode_loop_mutex);
|
||||
|
|
Loading…
Reference in a new issue