Adding threading to connect wiimotes simultaneously.

Adding threading to connect wiimotes simultaneously.

Postby altcoin » 19 Dec 2023, 18:51

Adding adding wiimotes takes a significant amount of time (2-5 sec per wiimote).

After looking into the STK/wiiuse codebase, I successfully sped up the connection of multiple wiimotes by threading the wiiuse_os_connect function of wiiuse/os_nix.c.
I am not experienced with threading, but it works great on Artix Linux, with STK compiled from git, It can connect two wiimotes as fast as one.

Wiiuse is not threadsafe (https://github.com/wiiuse/wiiuse/issues/109), but since the multithreading is done inside the wiiuse_os_connect() function, only wiiuse_os_connect_single() in os_nix.c must be threadsafe.
I see nothing in wiiuse_os_connect_single() that would be thread-problematic, but someone with more experience can verify that.

Code diff.

wiiuse/src/os.h
    Insert this struct to use for holding thread-specific data.
    {l Code}: {l Select All Code}
    struct wiiuse_connect_data_t {
        int ret;
        struct wiimote_t * wiimote;
        pthread_t thread_id;
    };


wiiuse/src/os_nix.c
    Include pthread.h for threading support.
    {l Code}: {l Select All Code}
    #include <pthread.h>


    Insert this wrapper for wiiuse_os_connect_single(), for pthread_create() to use.
    {l Code}: {l Select All Code}
    /**
     *     @brief pthread-compatible wrapper for wiiuse_os_connect_single.
     *
     *     @param wd       Pointer to a wiimote_connect_data_t structure.
     *
     */
    void wiiuse_os_connect_threaded(struct wiiuse_connect_data_t *wd) {
        wd->ret = wiiuse_os_connect_single(wd->wiimote, NULL);
    }



    Update the wiiuse_os_connect() function to look like this:
    {l Code}: {l Select All Code}
    /**
     *   @see wiiuse_connect()
     *   @see wiiuse_os_connect_threaded()
     */
    int wiiuse_os_connect(struct wiimote_t **wm, int wiimotes)
    {
        struct wiiuse_connect_data_t wd[wiimotes];
        int wd_len = 0;

        int connected = 0;
        int i         = 0;

        for (; i < wiimotes; ++i)
        {
            if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
            /* if the device address is not set, skip it */
            {
                continue;
            }

            wd[wd_len].wiimote = wm[i];
            wd[wd_len].ret = 0;

            pthread_create(&wd[wd_len].thread_id, NULL, &wiiuse_os_connect_threaded, &wd[wd_len]);
            wd_len ++;
        }

        for (i = 0; i < wd_len; i++) {
            pthread_join(wd[i].thread_id, NULL);

            if (wd[i].ret)
            {
                ++connected;
            }
        }

        return connected;
    }
altcoin
 
Posts: 17
Joined: 15 Apr 2021, 23:13

Who is online

Users browsing this forum: No registered users and 1 guest