src/thread/stdcpp/SDL_systhread.cpp
author Sam Lantinga <slouken@libsdl.org>
Thu, 13 Mar 2014 00:40:08 -0700
changeset 8615 097646deaef2
parent 8600 092802455aed
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fixed the copyright date on files contributed by David Ludwig
dludwig@8356
     1
/*
dludwig@8356
     2
  Simple DirectMedia Layer
slouken@8615
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
dludwig@8356
     4
dludwig@8356
     5
  This software is provided 'as-is', without any express or implied
dludwig@8356
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@8356
     7
  arising from the use of this software.
dludwig@8356
     8
dludwig@8356
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@8356
    10
  including commercial applications, and to alter it and redistribute it
dludwig@8356
    11
  freely, subject to the following restrictions:
dludwig@8356
    12
dludwig@8356
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@8356
    14
     claim that you wrote the original software. If you use this software
dludwig@8356
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@8356
    16
     appreciated but is not required.
dludwig@8356
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@8356
    18
     misrepresented as being the original software.
dludwig@8356
    19
  3. This notice may not be removed or altered from any source distribution.
dludwig@8356
    20
*/
dludwig@8600
    21
#include "../../SDL_internal.h"
dludwig@8356
    22
dludwig@8356
    23
/* Thread management routines for SDL */
dludwig@8356
    24
dludwig@8357
    25
extern "C" {
dludwig@8356
    26
#include "SDL_thread.h"
dludwig@8478
    27
#include "../SDL_thread_c.h"
dludwig@8356
    28
#include "../SDL_systhread.h"
dludwig@8360
    29
#include "SDL_log.h"
dludwig@8360
    30
}
dludwig@8360
    31
dludwig@8360
    32
#include <mutex>
dludwig@8360
    33
#include <thread>
dludwig@8484
    34
#include <system_error>
dludwig@8360
    35
dludwig@8486
    36
#ifdef __WINRT__
dludwig@8486
    37
#include <Windows.h>
dludwig@8360
    38
#endif
dludwig@8360
    39
dludwig@8360
    40
static void
dludwig@8360
    41
RunThread(void *args)
dludwig@8360
    42
{
dludwig@8360
    43
    SDL_RunThread(args);
dludwig@8357
    44
}
dludwig@8356
    45
dludwig@8357
    46
extern "C"
dludwig@8356
    47
int
dludwig@8356
    48
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
dludwig@8356
    49
{
dludwig@8360
    50
    try {
dludwig@8360
    51
        std::thread cpp_thread(RunThread, args);
dludwig@8360
    52
        thread->handle = (void *) new std::thread(std::move(cpp_thread));
dludwig@8360
    53
        return 0;
dludwig@8484
    54
    } catch (std::system_error & ex) {
dludwig@8484
    55
        SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what());
dludwig@8360
    56
        return -1;
dludwig@8484
    57
    } catch (std::bad_alloc &) {
dludwig@8484
    58
        SDL_OutOfMemory();
dludwig@8360
    59
        return -1;
dludwig@8360
    60
    }
dludwig@8356
    61
}
dludwig@8356
    62
dludwig@8357
    63
extern "C"
dludwig@8356
    64
void
dludwig@8356
    65
SDL_SYS_SetupThread(const char *name)
dludwig@8356
    66
{
dludwig@8360
    67
    // Make sure a thread ID gets assigned ASAP, for debugging purposes:
dludwig@8360
    68
    SDL_ThreadID();
dludwig@8356
    69
    return;
dludwig@8356
    70
}
dludwig@8356
    71
dludwig@8357
    72
extern "C"
dludwig@8356
    73
SDL_threadID
dludwig@8356
    74
SDL_ThreadID(void)
dludwig@8356
    75
{
dludwig@8486
    76
#ifdef __WINRT__
dludwig@8486
    77
    return GetCurrentThreadId();
dludwig@8486
    78
#else
dludwig@8486
    79
    // HACK: Mimick a thread ID, if one isn't otherwise available.
dludwig@8360
    80
    static thread_local SDL_threadID current_thread_id = 0;
dludwig@8360
    81
    static SDL_threadID next_thread_id = 1;
dludwig@8360
    82
    static std::mutex next_thread_id_mutex;
dludwig@8360
    83
dludwig@8360
    84
    if (current_thread_id == 0) {
dludwig@8360
    85
        std::lock_guard<std::mutex> lock(next_thread_id_mutex);
dludwig@8360
    86
        current_thread_id = next_thread_id;
dludwig@8360
    87
        ++next_thread_id;
dludwig@8360
    88
    }
dludwig@8360
    89
dludwig@8360
    90
    return current_thread_id;
dludwig@8486
    91
#endif
dludwig@8356
    92
}
dludwig@8356
    93
dludwig@8357
    94
extern "C"
dludwig@8356
    95
int
dludwig@8356
    96
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
dludwig@8356
    97
{
dludwig@8360
    98
    // Thread priorities do not look to be settable via C++11's thread
dludwig@8360
    99
    // interface, at least as of this writing (Nov 2012).  std::thread does
dludwig@8360
   100
    // provide access to the OS' native handle, however, and some form of
dludwig@8360
   101
    // priority-setting could, in theory, be done through this interface.
dludwig@8487
   102
    //
dludwig@8487
   103
    // WinRT: UPDATE (Aug 20, 2013): thread priorities cannot be changed
dludwig@8487
   104
    // on WinRT, at least not for any thread that's already been created.
dludwig@8487
   105
    // WinRT threads appear to be based off of the WinRT class,
dludwig@8487
   106
    // ThreadPool, more info on which can be found at:
dludwig@8487
   107
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.threading.threadpool.aspx
dludwig@8487
   108
    //
dludwig@8487
   109
    // For compatibility sake, 0 will be returned here.
dludwig@8356
   110
    return (0);
dludwig@8356
   111
}
dludwig@8356
   112
dludwig@8357
   113
extern "C"
dludwig@8356
   114
void
dludwig@8356
   115
SDL_SYS_WaitThread(SDL_Thread * thread)
dludwig@8356
   116
{
dludwig@8360
   117
    if ( ! thread) {
dludwig@8360
   118
        return;
dludwig@8360
   119
    }
dludwig@8360
   120
dludwig@8360
   121
    try {
dludwig@8360
   122
        std::thread * cpp_thread = (std::thread *) thread->handle;
dludwig@8360
   123
        if (cpp_thread->joinable()) {
dludwig@8360
   124
            cpp_thread->join();
dludwig@8360
   125
        }
dludwig@8484
   126
    } catch (std::system_error &) {
dludwig@8484
   127
        // An error occurred when joining the thread.  SDL_WaitThread does not,
dludwig@8484
   128
        // however, seem to provide a means to report errors to its callers
dludwig@8484
   129
        // though!
dludwig@8360
   130
    }
dludwig@8356
   131
}
dludwig@8356
   132
dludwig@8478
   133
extern "C"
dludwig@8544
   134
void
dludwig@8544
   135
SDL_SYS_DetachThread(SDL_Thread * thread)
dludwig@8544
   136
{
dludwig@8544
   137
    if ( ! thread) {
dludwig@8544
   138
        return;
dludwig@8544
   139
    }
dludwig@8544
   140
dludwig@8544
   141
    try {
dludwig@8544
   142
        std::thread * cpp_thread = (std::thread *) thread->handle;
dludwig@8544
   143
        if (cpp_thread->joinable()) {
dludwig@8544
   144
            cpp_thread->detach();
dludwig@8544
   145
        }
dludwig@8544
   146
    } catch (std::system_error &) {
dludwig@8544
   147
        // An error occurred when detaching the thread.  SDL_DetachThread does not,
dludwig@8544
   148
        // however, seem to provide a means to report errors to its callers
dludwig@8544
   149
        // though!
dludwig@8544
   150
    }
dludwig@8544
   151
}
dludwig@8544
   152
dludwig@8544
   153
extern "C"
slouken@8582
   154
SDL_TLSData *
slouken@8582
   155
SDL_SYS_GetTLSData()
slouken@8582
   156
{
slouken@8582
   157
    return SDL_Generic_GetTLSData();
slouken@8582
   158
}
slouken@8582
   159
slouken@8582
   160
extern "C"
slouken@8582
   161
int
slouken@8582
   162
SDL_SYS_SetTLSData(SDL_TLSData *data)
slouken@8582
   163
{
slouken@8582
   164
    return SDL_Generic_SetTLSData(data);
dludwig@8478
   165
}
dludwig@8478
   166
dludwig@8356
   167
/* vi: set ts=4 sw=4 expandtab: */