mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
HID worker thread is now operational
== DETAILS After wasting some cycles trying to isolate a crash, I went back to basics. I enabled the network logging, and put in a bunch of logging lines, and noticed that the HID thread wasn't actually starting. I did quite a bit of experimenting, working with different memory alignments, and finally got it working. == TESTING As you can see, I put a log output inside the worker thread. When I run the build, I can see the TICK messages. I can also see that the thread shuts down as expected. Also! The HID callback works as expected too! I have the GC adapter, and when I register the HID callback it fires and I get the following data: [INFO] USB device attach event [INFO] handle: 2058729 [INFO] physical_device_inst: 0 [INFO] vid: 0x7e05 [INFO] pid: 0x3703 [INFO] interface_index: 0 [INFO] sub_class: 0 [INFO] protocol: 0 [INFO] max_packet_size_rx: 37 [INFO] max_packet_size_tx: 5 Note that these are raw dumps of the data passed to the method, so e.g. the VID/PID might be byte-swapped from how they're usually represented. Have not done the stress test to try to reproduce the crash.
This commit is contained in:
parent
192f5875b9
commit
e98b006715
@ -24,64 +24,9 @@
|
||||
#include "../input_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
<<<<<<< HEAD
|
||||
#define POLL_THREAD_SLEEP 10000
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
|
||||
typedef struct wiiu_hid_user wiiu_hid_user_t;
|
||||
|
||||
struct wiiu_hid_user
|
||||
{
|
||||
wiiu_hid_user_t *next;
|
||||
uint8_t *send_control_buffer;
|
||||
uint8_t *send_control_type;
|
||||
|
||||
uint32_t handle;
|
||||
uint32_t physical_device_inst;
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
uint8_t interface_index;
|
||||
uint8_t sub_class;
|
||||
uint8_t protocol;
|
||||
uint16_t max_packet_size_rx;
|
||||
uint16_t max_packet_size_tx;
|
||||
};
|
||||
|
||||
typedef struct wiiu_hid
|
||||
{
|
||||
HIDClient *client;
|
||||
OSThread *polling_thread;
|
||||
// memory accounting; keep a pointer to the stack buffer so we can clean up later.
|
||||
void *polling_thread_stack;
|
||||
// setting this to true tells the polling thread to quit
|
||||
volatile bool polling_thread_quit;
|
||||
} wiiu_hid_t;
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
|
||||
<<<<<<< HEAD
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
|
||||
typedef struct wiiu_hid_user wiiu_hid_user_t;
|
||||
|
||||
<<<<<<< HEAD
|
||||
struct wiiu_hid_user
|
||||
{
|
||||
wiiu_hid_user_t *next;
|
||||
uint8_t *buffer;
|
||||
uint32_t transfersize;
|
||||
uint32_t handle;
|
||||
};
|
||||
=======
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
#define ALIGN_POINTER sizeof(void *)
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
|
||||
typedef struct wiiu_hid
|
||||
{
|
||||
HIDClient *client;
|
||||
@ -90,57 +35,17 @@ typedef struct wiiu_hid
|
||||
volatile bool polling_thread_quit;
|
||||
} wiiu_hid_t;
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
/*
|
||||
* The attach/detach callback has no access to the wiiu_hid_t object. Therefore, we need a
|
||||
* global place to handle device data.
|
||||
*/
|
||||
static wiiu_hid_user_t *pad_list = NULL;
|
||||
static OSFastMutex *pad_list_mutex;
|
||||
|
||||
static wiiu_hid_t *new_wiiu_hid_t(void);
|
||||
static void delete_wiiu_hid_t(wiiu_hid_t *hid);
|
||||
static wiiu_hid_user_t *new_wiiu_hid_user_t(void);
|
||||
static void delete_wiiu_hid_user_t(wiiu_hid_user_t *user);
|
||||
=======
|
||||
void *alloc_zeroed(size_t alignment, size_t size);
|
||||
static OSThread *new_thread(void);
|
||||
static wiiu_hid_t *new_hid(void);
|
||||
static void delete_hid(wiiu_hid_t *hid);
|
||||
static void delete_hidclient(HIDClient *client);
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
static HIDClient *new_hidclient(void);
|
||||
|
||||
<<<<<<< HEAD
|
||||
static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
|
||||
=======
|
||||
//static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
static void start_polling_thread(wiiu_hid_t *hid);
|
||||
static void stop_polling_thread(wiiu_hid_t *hid);
|
||||
static int wiiu_hid_polling_thread(int argc, const char **argv);
|
||||
static void wiiu_hid_do_poll(wiiu_hid_t *hid);
|
||||
<<<<<<< HEAD
|
||||
|
||||
static void enqueue_device(void);
|
||||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
|
||||
//HIDClient *new_hidclient(void);
|
||||
//void delete_hidclient(HIDClient *client);
|
||||
wiiu_hid_t *new_hid(void);
|
||||
void delete_hid(wiiu_hid_t *hid);
|
||||
|
||||
/**
|
||||
* HID driver entrypoints registered with hid_driver_t
|
||||
*/
|
||||
=======
|
||||
static void start_polling_thread(wiiu_hid_t *hid);
|
||||
static void stop_polling_thread(wiiu_hid_t *hid);
|
||||
static int wiiu_hid_polling_thread(int argc, const char **argv);
|
||||
static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
|
||||
static bool wiiu_hid_joypad_query(void *data, unsigned pad)
|
||||
{
|
||||
@ -149,7 +54,6 @@ static bool wiiu_hid_joypad_query(void *data, unsigned pad)
|
||||
|
||||
static const char *wiiu_hid_joypad_name(void *data, unsigned pad)
|
||||
{
|
||||
/* TODO/FIXME - implement properly */
|
||||
if (pad >= MAX_USERS)
|
||||
return NULL;
|
||||
|
||||
@ -195,48 +99,26 @@ static int16_t wiiu_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis)
|
||||
|
||||
static void *wiiu_hid_init(void)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
wiiu_hid_t *hid = new_hid();
|
||||
// HIDClient *client = new_hidclient();
|
||||
|
||||
// if(!hid || !client)
|
||||
if(!hid)
|
||||
goto error;
|
||||
|
||||
start_polling_thread(hid);
|
||||
if(hid->polling_thread == NULL)
|
||||
goto error;
|
||||
|
||||
// HIDAddClient(client, wiiu_attach_callback);
|
||||
// hid->client = client;
|
||||
|
||||
return hid;
|
||||
|
||||
error:
|
||||
if(hid) {
|
||||
stop_polling_thread(hid);
|
||||
delete_hid(hid);
|
||||
}
|
||||
// if(client) {
|
||||
// delete_hidclient(client);
|
||||
// }
|
||||
|
||||
return NULL;
|
||||
=======
|
||||
HIDSetup();
|
||||
RARCH_LOG("[hid]: wiiu_hid: init\n");
|
||||
// HIDSetup();
|
||||
wiiu_hid_t *hid = new_hid();
|
||||
HIDClient *client = new_hidclient();
|
||||
if(!hid || !client) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
RARCH_LOG("[hid]: hid: 0x%x\n", hid);
|
||||
RARCH_LOG("[hid]: client: 0x%x\n", client);
|
||||
|
||||
start_polling_thread(hid);
|
||||
if(!hid->polling_thread)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[hid]: Registering HIDClient\n");
|
||||
HIDAddClient(client, wiiu_attach_callback);
|
||||
hid->client = client;
|
||||
|
||||
RARCH_LOG("[hid]: init success");
|
||||
return hid;
|
||||
|
||||
error:
|
||||
@ -245,47 +127,10 @@ static void *wiiu_hid_init(void)
|
||||
delete_hid(hid);
|
||||
delete_hidclient(client);
|
||||
return NULL;
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
}
|
||||
|
||||
static void wiiu_hid_free(void *data)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
wiiu_hid_t *hid = (wiiu_hid_t*)data;
|
||||
|
||||
if (hid) {
|
||||
stop_polling_thread(hid);
|
||||
<<<<<<< HEAD
|
||||
delete_wiiu_hid_t(hid);
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
static void free_pad_list(void) {
|
||||
wiiu_hid_user_t *top;
|
||||
|
||||
while(pad_list != NULL) {
|
||||
top = pad_list;
|
||||
pad_list = top->next;
|
||||
delete_wiiu_hid_user_t(top);
|
||||
=======
|
||||
delete_hid(hid);
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
/**
|
||||
* This is a no-op because polling is done with a worker thread.
|
||||
*/
|
||||
=======
|
||||
wiiu_hid_t *hid = (wiiu_hid_t*)data;
|
||||
|
||||
if (hid) {
|
||||
@ -293,10 +138,9 @@ static void free_pad_list(void) {
|
||||
delete_hidclient(hid->client);
|
||||
delete_hid(hid);
|
||||
}
|
||||
HIDTeardown();
|
||||
//HIDTeardown();
|
||||
}
|
||||
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
static void wiiu_hid_poll(void *data)
|
||||
{
|
||||
(void)data;
|
||||
@ -304,73 +148,37 @@ static void wiiu_hid_poll(void *data)
|
||||
|
||||
static void start_polling_thread(wiiu_hid_t *hid) {
|
||||
RARCH_LOG("[hid]: starting polling thread.\n");
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2 |
|
||||
OS_THREAD_ATTRIB_STACK_USAGE;
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2;
|
||||
BOOL result;
|
||||
|
||||
int32_t stack_size = 0x8000;
|
||||
int32_t priority = 10;
|
||||
OSThread *thread = memalign(ALIGN_POINTER, sizeof(OSThread));
|
||||
void *stack = memalign(ALIGN_POINTER, stack_size);
|
||||
OSThread *thread = new_thread();
|
||||
void *stack = alloc_zeroed(16, stack_size);
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
if(pad_list_mutex == NULL) {
|
||||
pad_list_mutex = new_fastmutex("pad_list");
|
||||
}
|
||||
|
||||
if(!thread || !stack || !pad_list_mutex)
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
if(!thread || !stack)
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
if(!thread || !stack)
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
goto error;
|
||||
=======
|
||||
if(!thread || !stack) {
|
||||
RARCH_LOG("[hid]: allocation failed, aborting thread start.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
RARCH_LOG("[hid]: thread = %x; stack = %x\n", thread, stack);
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
RARCH_LOG("[hid]: thread: 0x%x; stack: 0x%x\n", thread, stack);
|
||||
|
||||
if(!OSCreateThread(thread, wiiu_hid_polling_thread, 1, (char *)hid, stack, stack_size, priority, attributes)) {
|
||||
if(!OSCreateThread(thread,
|
||||
wiiu_hid_polling_thread,
|
||||
1, (char *)hid,
|
||||
stack+stack_size, stack_size,
|
||||
priority,
|
||||
attributes)) {
|
||||
RARCH_LOG("[hid]: OSCreateThread failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
hid->polling_thread = thread;
|
||||
hid->polling_thread_stack = stack;
|
||||
OSResumeThread(thread);
|
||||
return;
|
||||
|
||||
error:
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
if(pad_list_mutex)
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
if(pad_list_mutex)
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
if(stack)
|
||||
free(stack);
|
||||
=======
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
if(thread)
|
||||
free(thread);
|
||||
if(stack)
|
||||
@ -391,28 +199,8 @@ static void stop_polling_thread(wiiu_hid_t *hid) {
|
||||
OSJoinThread(hid->polling_thread, &thread_result);
|
||||
free(hid->polling_thread);
|
||||
free(hid->polling_thread_stack);
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
|
||||
// with the thread stopped, we don't need the mutex.
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
pad_list_mutex = NULL;
|
||||
free_pad_list();
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
=======
|
||||
hid->polling_thread = NULL;
|
||||
hid->polling_thread_stack = NULL;
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
}
|
||||
|
||||
void log_device(HIDDevice *device) {
|
||||
@ -420,60 +208,6 @@ void log_device(HIDDevice *device) {
|
||||
RARCH_LOG("NULL device.\n");
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only call this from the polling thread.
|
||||
*/
|
||||
static void wiiu_hid_do_poll(wiiu_hid_t *hid) {
|
||||
usleep(POLL_THREAD_SLEEP);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
int32_t wiiu_attach_device(HIDClient *client, HIDDevice *device) {
|
||||
wiiu_hid_user_t *adapter = new_wiiu_hid_user_t();
|
||||
|
||||
if(!adapter)
|
||||
goto error;
|
||||
|
||||
error:
|
||||
if(adapter) {
|
||||
delete_wiiu_hid_user_t(adapter);
|
||||
}
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
|
||||
int32_t wiiu_detach_device(HIDClient *client, HIDDevice *device) {
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
/**
|
||||
* Callbacks
|
||||
*/
|
||||
/*
|
||||
int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach) {
|
||||
int32_t result = DEVICE_UNUSED;
|
||||
|
||||
switch(attach) {
|
||||
case HID_DEVICE_ATTACH:
|
||||
RARCH_LOG("Device attached\n");
|
||||
break;
|
||||
case HID_DEVICE_DETACH:
|
||||
RARCH_LOG("Device detached\n");
|
||||
=======
|
||||
RARCH_LOG(" handle: %d\n", device->handle);
|
||||
RARCH_LOG(" physical_device_inst: %d\n", device->physical_device_inst);
|
||||
RARCH_LOG(" vid: 0x%x\n", device->vid);
|
||||
@ -492,7 +226,6 @@ static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32
|
||||
break;
|
||||
case HID_DEVICE_DETACH:
|
||||
RARCH_LOG("USB device detach event\n");
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -501,60 +234,49 @@ static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32
|
||||
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
*/
|
||||
/**
|
||||
* Allocation
|
||||
*/
|
||||
|
||||
wiiu_hid_t *new_hid(void) {
|
||||
wiiu_hid_t *hid = calloc(1, sizeof(wiiu_hid_t));
|
||||
if(hid)
|
||||
memset(hid, 0, sizeof(wiiu_hid_t));
|
||||
|
||||
return hid;
|
||||
=======
|
||||
|
||||
static int wiiu_hid_polling_thread(int argc, const char **argv) {
|
||||
wiiu_hid_t *hid = (wiiu_hid_t *)argv;
|
||||
int i = 0;
|
||||
RARCH_LOG("[hid]: polling thread is starting\n");
|
||||
while(!hid->polling_thread_quit) {
|
||||
usleep(10000);
|
||||
i += 10000;
|
||||
if(i >= (1000 * 1000 * 3)) {
|
||||
RARCH_LOG("[hid]: thread: TICK!\n");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RARCH_LOG("[hid]: polling thread is stopping\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static OSThread *new_thread(void) {
|
||||
OSThread *t = alloc_zeroed(8, sizeof(OSThread));
|
||||
t->tag = OS_THREAD_TAG;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static wiiu_hid_t *new_hid(void) {
|
||||
return alloc_zeroed(2, sizeof(wiiu_hid_t));
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
RARCH_LOG("[hid]: new_hid()\n");
|
||||
return alloc_zeroed(4, sizeof(wiiu_hid_t));
|
||||
}
|
||||
|
||||
static void delete_hid(wiiu_hid_t *hid) {
|
||||
RARCH_LOG("[hid]: delete_hid()\n");
|
||||
if(hid)
|
||||
free(hid);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
HIDClient *new_hidclient(void) {
|
||||
HIDClient *client = memalign(32, sizeof(HIDClient));
|
||||
if(client)
|
||||
memset(client, 0, sizeof(HIDClient));
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
void delete_hidclient(HIDClient *client) {
|
||||
if(client)
|
||||
free(client);
|
||||
}
|
||||
*/
|
||||
=======
|
||||
|
||||
static HIDClient *new_hidclient(void) {
|
||||
RARCH_LOG("[hid]: new_hidclient()\n");
|
||||
return alloc_zeroed(32, sizeof(HIDClient));
|
||||
}
|
||||
|
||||
static void delete_hidclient(HIDClient *client) {
|
||||
RARCH_LOG("[hid]: delete_hidclient()\n");
|
||||
if(client)
|
||||
free(client);
|
||||
}
|
||||
@ -569,7 +291,6 @@ void *alloc_zeroed(size_t alignment, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
>>>>>>> Simplify, add logging, revert some of the changes
|
||||
hid_driver_t wiiu_hid = {
|
||||
wiiu_hid_init,
|
||||
wiiu_hid_joypad_query,
|
||||
@ -580,5 +301,5 @@ hid_driver_t wiiu_hid = {
|
||||
wiiu_hid_poll,
|
||||
wiiu_hid_joypad_rumble,
|
||||
wiiu_hid_joypad_name,
|
||||
"wiiu_usb",
|
||||
"wiiu",
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user