src/thread/generic/SDL_sysmutex.c
author Ryan C. Gordon
Mon, 23 Jan 2017 12:06:10 -0500
changeset 10837 c2f241c2f6ad
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
audio: Fix same bug as last commit, but for _mm_bslli_si128 vs _mm_slli_si128.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@0
    22
slouken@0
    23
/* An implementation of mutexes using semaphores */
slouken@0
    24
slouken@0
    25
#include "SDL_thread.h"
slouken@0
    26
#include "SDL_systhread_c.h"
slouken@0
    27
slouken@0
    28
slouken@1895
    29
struct SDL_mutex
slouken@1895
    30
{
slouken@1895
    31
    int recursive;
slouken@3578
    32
    SDL_threadID owner;
slouken@1895
    33
    SDL_sem *sem;
slouken@0
    34
};
slouken@0
    35
slouken@0
    36
/* Create a mutex */
slouken@1895
    37
SDL_mutex *
slouken@1895
    38
SDL_CreateMutex(void)
slouken@0
    39
{
slouken@1895
    40
    SDL_mutex *mutex;
slouken@0
    41
slouken@1895
    42
    /* Allocate mutex memory */
slouken@1895
    43
    mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
slouken@1895
    44
    if (mutex) {
slouken@1895
    45
        /* Create the mutex semaphore, with initial value 1 */
slouken@1895
    46
        mutex->sem = SDL_CreateSemaphore(1);
slouken@1895
    47
        mutex->recursive = 0;
slouken@1895
    48
        mutex->owner = 0;
slouken@1895
    49
        if (!mutex->sem) {
slouken@1895
    50
            SDL_free(mutex);
slouken@1895
    51
            mutex = NULL;
slouken@1895
    52
        }
slouken@1895
    53
    } else {
slouken@1895
    54
        SDL_OutOfMemory();
slouken@1895
    55
    }
slouken@1895
    56
    return mutex;
slouken@0
    57
}
slouken@0
    58
slouken@0
    59
/* Free the mutex */
slouken@1895
    60
void
slouken@1895
    61
SDL_DestroyMutex(SDL_mutex * mutex)
slouken@0
    62
{
slouken@1895
    63
    if (mutex) {
slouken@1895
    64
        if (mutex->sem) {
slouken@1895
    65
            SDL_DestroySemaphore(mutex->sem);
slouken@1895
    66
        }
slouken@1895
    67
        SDL_free(mutex);
slouken@1895
    68
    }
slouken@0
    69
}
slouken@0
    70
urkle@6966
    71
/* Lock the mutex */
slouken@1895
    72
int
slouken@6977
    73
SDL_LockMutex(SDL_mutex * mutex)
slouken@0
    74
{
slouken@1361
    75
#if SDL_THREADS_DISABLED
slouken@1895
    76
    return 0;
slouken@0
    77
#else
slouken@3578
    78
    SDL_threadID this_thread;
slouken@0
    79
slouken@1895
    80
    if (mutex == NULL) {
icculus@7037
    81
        return SDL_SetError("Passed a NULL mutex");
slouken@1895
    82
    }
slouken@0
    83
slouken@1895
    84
    this_thread = SDL_ThreadID();
slouken@1895
    85
    if (mutex->owner == this_thread) {
slouken@1895
    86
        ++mutex->recursive;
slouken@1895
    87
    } else {
slouken@1895
    88
        /* The order of operations is important.
slouken@1895
    89
           We set the locking thread id after we obtain the lock
slouken@1895
    90
           so unlocks from other threads will fail.
slouken@1895
    91
         */
slouken@1895
    92
        SDL_SemWait(mutex->sem);
slouken@1895
    93
        mutex->owner = this_thread;
slouken@1895
    94
        mutex->recursive = 0;
slouken@1895
    95
    }
slouken@0
    96
slouken@1895
    97
    return 0;
slouken@1361
    98
#endif /* SDL_THREADS_DISABLED */
slouken@0
    99
}
slouken@0
   100
urkle@6966
   101
/* try Lock the mutex */
urkle@6966
   102
int
urkle@6966
   103
SDL_TryLockMutex(SDL_mutex * mutex)
urkle@6966
   104
{
urkle@6966
   105
#if SDL_THREADS_DISABLED
urkle@6966
   106
    return 0;
urkle@6966
   107
#else
urkle@6966
   108
    int retval = 0;
urkle@6966
   109
    SDL_threadID this_thread;
urkle@6966
   110
urkle@6966
   111
    if (mutex == NULL) {
icculus@7037
   112
        return SDL_SetError("Passed a NULL mutex");
urkle@6966
   113
    }
urkle@6966
   114
urkle@6966
   115
    this_thread = SDL_ThreadID();
urkle@6966
   116
    if (mutex->owner == this_thread) {
urkle@6966
   117
        ++mutex->recursive;
urkle@6966
   118
    } else {
urkle@6966
   119
        /* The order of operations is important.
urkle@6966
   120
         We set the locking thread id after we obtain the lock
urkle@6966
   121
         so unlocks from other threads will fail.
urkle@6966
   122
         */
urkle@6966
   123
        retval = SDL_SemWait(mutex->sem);
urkle@6966
   124
        if (retval == 0) {
urkle@6966
   125
            mutex->owner = this_thread;
urkle@6966
   126
            mutex->recursive = 0;
urkle@6966
   127
        }
urkle@6966
   128
    }
urkle@6966
   129
urkle@6966
   130
    return retval;
urkle@6966
   131
#endif /* SDL_THREADS_DISABLED */
urkle@6966
   132
}
urkle@6966
   133
slouken@0
   134
/* Unlock the mutex */
slouken@1895
   135
int
slouken@1895
   136
SDL_mutexV(SDL_mutex * mutex)
slouken@0
   137
{
slouken@1361
   138
#if SDL_THREADS_DISABLED
slouken@1895
   139
    return 0;
slouken@0
   140
#else
slouken@1895
   141
    if (mutex == NULL) {
icculus@7037
   142
        return SDL_SetError("Passed a NULL mutex");
slouken@1895
   143
    }
slouken@0
   144
slouken@1895
   145
    /* If we don't own the mutex, we can't unlock it */
slouken@1895
   146
    if (SDL_ThreadID() != mutex->owner) {
icculus@7037
   147
        return SDL_SetError("mutex not owned by this thread");
slouken@1895
   148
    }
slouken@0
   149
slouken@1895
   150
    if (mutex->recursive) {
slouken@1895
   151
        --mutex->recursive;
slouken@1895
   152
    } else {
slouken@1895
   153
        /* The order of operations is important.
slouken@1895
   154
           First reset the owner so another thread doesn't lock
slouken@1895
   155
           the mutex and set the ownership before we reset it,
slouken@1895
   156
           then release the lock semaphore.
slouken@1895
   157
         */
slouken@1895
   158
        mutex->owner = 0;
slouken@1895
   159
        SDL_SemPost(mutex->sem);
slouken@1895
   160
    }
slouken@1895
   161
    return 0;
slouken@1361
   162
#endif /* SDL_THREADS_DISABLED */
slouken@0
   163
}
slouken@1895
   164
slouken@1895
   165
/* vi: set ts=4 sw=4 expandtab: */