sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_systhread.cpp (4498B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 #include "../../SDL_internal.h"
     22 
     23 /* Thread management routines for SDL */
     24 
     25 extern "C" {
     26 #include "SDL_thread.h"
     27 #include "../SDL_thread_c.h"
     28 #include "../SDL_systhread.h"
     29 }
     30 
     31 #include <mutex>
     32 #include <thread>
     33 #include <system_error>
     34 
     35 #ifdef __WINRT__
     36 #include <Windows.h>
     37 #endif
     38 
     39 static void
     40 RunThread(void *args)
     41 {
     42     SDL_RunThread((SDL_Thread *) args);
     43 }
     44 
     45 extern "C"
     46 int
     47 SDL_SYS_CreateThread(SDL_Thread * thread)
     48 {
     49     try {
     50         // !!! FIXME: no way to set a thread stack size here.
     51         std::thread cpp_thread(RunThread, thread);
     52         thread->handle = (void *) new std::thread(std::move(cpp_thread));
     53         return 0;
     54     } catch (std::system_error & ex) {
     55         SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what());
     56         return -1;
     57     } catch (std::bad_alloc &) {
     58         SDL_OutOfMemory();
     59         return -1;
     60     }
     61 }
     62 
     63 extern "C"
     64 void
     65 SDL_SYS_SetupThread(const char *name)
     66 {
     67     // Make sure a thread ID gets assigned ASAP, for debugging purposes:
     68     SDL_ThreadID();
     69     return;
     70 }
     71 
     72 extern "C"
     73 SDL_threadID
     74 SDL_ThreadID(void)
     75 {
     76 #ifdef __WINRT__
     77     return GetCurrentThreadId();
     78 #else
     79     // HACK: Mimick a thread ID, if one isn't otherwise available.
     80     static thread_local SDL_threadID current_thread_id = 0;
     81     static SDL_threadID next_thread_id = 1;
     82     static std::mutex next_thread_id_mutex;
     83 
     84     if (current_thread_id == 0) {
     85         std::lock_guard<std::mutex> lock(next_thread_id_mutex);
     86         current_thread_id = next_thread_id;
     87         ++next_thread_id;
     88     }
     89 
     90     return current_thread_id;
     91 #endif
     92 }
     93 
     94 extern "C"
     95 int
     96 SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
     97 {
     98 #ifdef __WINRT__
     99     int value;
    100 
    101     if (priority == SDL_THREAD_PRIORITY_LOW) {
    102         value = THREAD_PRIORITY_LOWEST;
    103     }
    104     else if (priority == SDL_THREAD_PRIORITY_HIGH) {
    105         value = THREAD_PRIORITY_HIGHEST;
    106     }
    107     else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
    108         // FIXME: WinRT does not support TIME_CRITICAL! -flibit
    109         SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST");
    110         value = THREAD_PRIORITY_HIGHEST;
    111     }
    112     else {
    113         value = THREAD_PRIORITY_NORMAL;
    114     }
    115     if (!SetThreadPriority(GetCurrentThread(), value)) {
    116         return WIN_SetError("SetThreadPriority()");
    117     }
    118     return 0;
    119 #else
    120     return SDL_Unsupported();
    121 #endif
    122 }
    123 
    124 extern "C"
    125 void
    126 SDL_SYS_WaitThread(SDL_Thread * thread)
    127 {
    128     if ( ! thread) {
    129         return;
    130     }
    131 
    132     try {
    133         std::thread * cpp_thread = (std::thread *) thread->handle;
    134         if (cpp_thread->joinable()) {
    135             cpp_thread->join();
    136         }
    137     } catch (std::system_error &) {
    138         // An error occurred when joining the thread.  SDL_WaitThread does not,
    139         // however, seem to provide a means to report errors to its callers
    140         // though!
    141     }
    142 }
    143 
    144 extern "C"
    145 void
    146 SDL_SYS_DetachThread(SDL_Thread * thread)
    147 {
    148     if ( ! thread) {
    149         return;
    150     }
    151 
    152     try {
    153         std::thread * cpp_thread = (std::thread *) thread->handle;
    154         if (cpp_thread->joinable()) {
    155             cpp_thread->detach();
    156         }
    157     } catch (std::system_error &) {
    158         // An error occurred when detaching the thread.  SDL_DetachThread does not,
    159         // however, seem to provide a means to report errors to its callers
    160         // though!
    161     }
    162 }
    163 
    164 extern "C"
    165 SDL_TLSData *
    166 SDL_SYS_GetTLSData(void)
    167 {
    168     return SDL_Generic_GetTLSData();
    169 }
    170 
    171 extern "C"
    172 int
    173 SDL_SYS_SetTLSData(SDL_TLSData *data)
    174 {
    175     return SDL_Generic_SetTLSData(data);
    176 }
    177 
    178 /* vi: set ts=4 sw=4 expandtab: */