src/thread/nds/SDL_sysmutex.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 27 Aug 2008 15:10:03 +0000
changeset 2735 204be4fc2726
child 2859 99210400e8b9
permissions -rw-r--r--
Final merge of Google Summer of Code 2008 work...

Port SDL 1.3 to the Nintendo DS
by Darren Alton, mentored by Sam Lantinga
slouken@2735
     1
/*
slouken@2735
     2
    SDL - Simple DirectMedia Layer
slouken@2735
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
slouken@2735
     4
slouken@2735
     5
    This library is free software; you can redistribute it and/or
slouken@2735
     6
    modify it under the terms of the GNU Library General Public
slouken@2735
     7
    License as published by the Free Software Foundation; either
slouken@2735
     8
    version 2 of the License, or (at your option) any later version.
slouken@2735
     9
slouken@2735
    10
    This library is distributed in the hope that it will be useful,
slouken@2735
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@2735
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@2735
    13
    Library General Public License for more details.
slouken@2735
    14
slouken@2735
    15
    You should have received a copy of the GNU Library General Public
slouken@2735
    16
    License along with this library; if not, write to the Free
slouken@2735
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@2735
    18
slouken@2735
    19
    Sam Lantinga
slouken@2735
    20
    slouken@devolution.com
slouken@2735
    21
*/
slouken@2735
    22
slouken@2735
    23
#ifdef SAVE_RCSID
slouken@2735
    24
static char rcsid =
slouken@2735
    25
    "@(#) $Id: SDL_sysmutex.c,v 1.2 2001/04/26 16:50:18 hercules Exp $";
slouken@2735
    26
#endif
slouken@2735
    27
slouken@2735
    28
/* An implementation of mutexes using semaphores */
slouken@2735
    29
slouken@2735
    30
#include <stdio.h>
slouken@2735
    31
#include <stdlib.h>
slouken@2735
    32
slouken@2735
    33
#include "SDL_error.h"
slouken@2735
    34
#include "SDL_thread.h"
slouken@2735
    35
#include "SDL_systhread_c.h"
slouken@2735
    36
slouken@2735
    37
slouken@2735
    38
struct SDL_mutex
slouken@2735
    39
{
slouken@2735
    40
    int recursive;
slouken@2735
    41
    Uint32 owner;
slouken@2735
    42
    SDL_sem *sem;
slouken@2735
    43
};
slouken@2735
    44
slouken@2735
    45
/* Create a mutex */
slouken@2735
    46
SDL_mutex *
slouken@2735
    47
SDL_CreateMutex(void)
slouken@2735
    48
{
slouken@2735
    49
    SDL_mutex *mutex;
slouken@2735
    50
slouken@2735
    51
    /* Allocate mutex memory */
slouken@2735
    52
    mutex = (SDL_mutex *) malloc(sizeof(*mutex));
slouken@2735
    53
    if (mutex) {
slouken@2735
    54
        /* Create the mutex semaphore, with initial value 1 */
slouken@2735
    55
        mutex->sem = SDL_CreateSemaphore(1);
slouken@2735
    56
        mutex->recursive = 0;
slouken@2735
    57
        mutex->owner = 0;
slouken@2735
    58
        if (!mutex->sem) {
slouken@2735
    59
            free(mutex);
slouken@2735
    60
            mutex = NULL;
slouken@2735
    61
        }
slouken@2735
    62
    } else {
slouken@2735
    63
        SDL_OutOfMemory();
slouken@2735
    64
    }
slouken@2735
    65
    return mutex;
slouken@2735
    66
}
slouken@2735
    67
slouken@2735
    68
/* Free the mutex */
slouken@2735
    69
void
slouken@2735
    70
SDL_DestroyMutex(SDL_mutex * mutex)
slouken@2735
    71
{
slouken@2735
    72
    if (mutex) {
slouken@2735
    73
        if (mutex->sem) {
slouken@2735
    74
            SDL_DestroySemaphore(mutex->sem);
slouken@2735
    75
        }
slouken@2735
    76
        free(mutex);
slouken@2735
    77
    }
slouken@2735
    78
}
slouken@2735
    79
slouken@2735
    80
/* Lock the semaphore */
slouken@2735
    81
int
slouken@2735
    82
SDL_mutexP(SDL_mutex * mutex)
slouken@2735
    83
{
slouken@2735
    84
#ifdef DISABLE_THREADS
slouken@2735
    85
    return 0;
slouken@2735
    86
#else
slouken@2735
    87
    Uint32 this_thread;
slouken@2735
    88
slouken@2735
    89
    if (mutex == NULL) {
slouken@2735
    90
        SDL_SetError("Passed a NULL mutex");
slouken@2735
    91
        return -1;
slouken@2735
    92
    }
slouken@2735
    93
slouken@2735
    94
    this_thread = SDL_ThreadID();
slouken@2735
    95
    if (mutex->owner == this_thread) {
slouken@2735
    96
        ++mutex->recursive;
slouken@2735
    97
    } else {
slouken@2735
    98
        /* The order of operations is important.
slouken@2735
    99
           We set the locking thread id after we obtain the lock
slouken@2735
   100
           so unlocks from other threads will fail.
slouken@2735
   101
         */
slouken@2735
   102
        SDL_SemWait(mutex->sem);
slouken@2735
   103
        mutex->owner = this_thread;
slouken@2735
   104
        mutex->recursive = 0;
slouken@2735
   105
    }
slouken@2735
   106
slouken@2735
   107
    return 0;
slouken@2735
   108
#endif /* DISABLE_THREADS */
slouken@2735
   109
}
slouken@2735
   110
slouken@2735
   111
/* Unlock the mutex */
slouken@2735
   112
int
slouken@2735
   113
SDL_mutexV(SDL_mutex * mutex)
slouken@2735
   114
{
slouken@2735
   115
#ifdef DISABLE_THREADS
slouken@2735
   116
    return 0;
slouken@2735
   117
#else
slouken@2735
   118
    if (mutex == NULL) {
slouken@2735
   119
        SDL_SetError("Passed a NULL mutex");
slouken@2735
   120
        return -1;
slouken@2735
   121
    }
slouken@2735
   122
slouken@2735
   123
    /* If we don't own the mutex, we can't unlock it */
slouken@2735
   124
    if (SDL_ThreadID() != mutex->owner) {
slouken@2735
   125
        SDL_SetError("mutex not owned by this thread");
slouken@2735
   126
        return -1;
slouken@2735
   127
    }
slouken@2735
   128
slouken@2735
   129
    if (mutex->recursive) {
slouken@2735
   130
        --mutex->recursive;
slouken@2735
   131
    } else {
slouken@2735
   132
        /* The order of operations is important.
slouken@2735
   133
           First reset the owner so another thread doesn't lock
slouken@2735
   134
           the mutex and set the ownership before we reset it,
slouken@2735
   135
           then release the lock semaphore.
slouken@2735
   136
         */
slouken@2735
   137
        mutex->owner = 0;
slouken@2735
   138
        SDL_SemPost(mutex->sem);
slouken@2735
   139
    }
slouken@2735
   140
    return 0;
slouken@2735
   141
#endif /* DISABLE_THREADS */
slouken@2735
   142
}