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