1062c5bc4SJason Schmidlapp /* 2062c5bc4SJason Schmidlapp * pthread_mutex_unlock.c 3062c5bc4SJason Schmidlapp * 4062c5bc4SJason Schmidlapp * Description: 5062c5bc4SJason Schmidlapp * This translation unit implements mutual exclusion (mutex) primitives. 6062c5bc4SJason Schmidlapp * 7062c5bc4SJason Schmidlapp * -------------------------------------------------------------------------- 8062c5bc4SJason Schmidlapp * 9062c5bc4SJason Schmidlapp * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems 10062c5bc4SJason Schmidlapp * Copyright(C) 2008 Jason Schmidlapp 11062c5bc4SJason Schmidlapp * 12062c5bc4SJason Schmidlapp * Contact Email: jschmidlapp@users.sourceforge.net 13062c5bc4SJason Schmidlapp * 14062c5bc4SJason Schmidlapp * 15062c5bc4SJason Schmidlapp * Based upon Pthreads-win32 - POSIX Threads Library for Win32 16062c5bc4SJason Schmidlapp * Copyright(C) 1998 John E. Bossom 17062c5bc4SJason Schmidlapp * Copyright(C) 1999,2005 Pthreads-win32 contributors 18062c5bc4SJason Schmidlapp * 19062c5bc4SJason Schmidlapp * Contact Email: rpj@callisto.canberra.edu.au 20062c5bc4SJason Schmidlapp * 21062c5bc4SJason Schmidlapp * The original list of contributors to the Pthreads-win32 project 22062c5bc4SJason Schmidlapp * is contained in the file CONTRIBUTORS.ptw32 included with the 23062c5bc4SJason Schmidlapp * source code distribution. The list can also be seen at the 24062c5bc4SJason Schmidlapp * following World Wide Web location: 25062c5bc4SJason Schmidlapp * http://sources.redhat.com/pthreads-win32/contributors.html 26062c5bc4SJason Schmidlapp * 27062c5bc4SJason Schmidlapp * This library is free software; you can redistribute it and/or 28062c5bc4SJason Schmidlapp * modify it under the terms of the GNU Lesser General Public 29062c5bc4SJason Schmidlapp * License as published by the Free Software Foundation; either 30062c5bc4SJason Schmidlapp * version 2 of the License, or (at your option) any later version. 31062c5bc4SJason Schmidlapp * 32062c5bc4SJason Schmidlapp * This library is distributed in the hope that it will be useful, 33062c5bc4SJason Schmidlapp * but WITHOUT ANY WARRANTY; without even the implied warranty of 34062c5bc4SJason Schmidlapp * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35062c5bc4SJason Schmidlapp * Lesser General Public License for more details. 36062c5bc4SJason Schmidlapp * 37062c5bc4SJason Schmidlapp * You should have received a copy of the GNU Lesser General Public 38062c5bc4SJason Schmidlapp * License along with this library in the file COPYING.LIB; 39062c5bc4SJason Schmidlapp * if not, write to the Free Software Foundation, Inc., 40062c5bc4SJason Schmidlapp * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 41062c5bc4SJason Schmidlapp */ 42062c5bc4SJason Schmidlapp 43062c5bc4SJason Schmidlapp #include <pte_osal.h> 44062c5bc4SJason Schmidlapp 45062c5bc4SJason Schmidlapp #include <stdio.h> 46062c5bc4SJason Schmidlapp #include <stdlib.h> 47062c5bc4SJason Schmidlapp 48062c5bc4SJason Schmidlapp #include "pthread.h" 49062c5bc4SJason Schmidlapp #include "implement.h" 50062c5bc4SJason Schmidlapp 51062c5bc4SJason Schmidlapp 52062c5bc4SJason Schmidlapp #define TEST_IE InterlockedExchange 53062c5bc4SJason Schmidlapp 54062c5bc4SJason Schmidlapp int 55062c5bc4SJason Schmidlapp pthread_mutex_unlock (pthread_mutex_t * mutex) 56062c5bc4SJason Schmidlapp { 57062c5bc4SJason Schmidlapp int result = 0; 58062c5bc4SJason Schmidlapp pthread_mutex_t mx; 59062c5bc4SJason Schmidlapp 60062c5bc4SJason Schmidlapp /* 61062c5bc4SJason Schmidlapp * Let the system deal with invalid pointers. 62062c5bc4SJason Schmidlapp */ 63062c5bc4SJason Schmidlapp 64062c5bc4SJason Schmidlapp mx = *mutex; 65062c5bc4SJason Schmidlapp 66062c5bc4SJason Schmidlapp /* 67062c5bc4SJason Schmidlapp * If the thread calling us holds the mutex then there is no 68062c5bc4SJason Schmidlapp * race condition. If another thread holds the 69062c5bc4SJason Schmidlapp * lock then we shouldn't be in here. 70062c5bc4SJason Schmidlapp */ 71062c5bc4SJason Schmidlapp if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) 72062c5bc4SJason Schmidlapp { 73062c5bc4SJason Schmidlapp if (mx->kind == PTHREAD_MUTEX_NORMAL) 74062c5bc4SJason Schmidlapp { 75062c5bc4SJason Schmidlapp int idx; 76062c5bc4SJason Schmidlapp 77062c5bc4SJason Schmidlapp idx = PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0); 78062c5bc4SJason Schmidlapp if (idx != 0) 79062c5bc4SJason Schmidlapp { 80062c5bc4SJason Schmidlapp if (idx < 0) 81062c5bc4SJason Schmidlapp { 82062c5bc4SJason Schmidlapp /* 83062c5bc4SJason Schmidlapp * Someone may be waiting on that mutex. 84062c5bc4SJason Schmidlapp */ 85062c5bc4SJason Schmidlapp if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK) 86062c5bc4SJason Schmidlapp { 87062c5bc4SJason Schmidlapp result = EINVAL; 88062c5bc4SJason Schmidlapp } 89062c5bc4SJason Schmidlapp } 90062c5bc4SJason Schmidlapp } 91062c5bc4SJason Schmidlapp else 92062c5bc4SJason Schmidlapp { 93062c5bc4SJason Schmidlapp /* 94062c5bc4SJason Schmidlapp * Was not locked (so can't be owned by us). 95062c5bc4SJason Schmidlapp */ 96062c5bc4SJason Schmidlapp result = EPERM; 97062c5bc4SJason Schmidlapp } 98062c5bc4SJason Schmidlapp } 99062c5bc4SJason Schmidlapp else 100062c5bc4SJason Schmidlapp { 101062c5bc4SJason Schmidlapp if (pthread_equal (mx->ownerThread, pthread_self ())) 102062c5bc4SJason Schmidlapp { 103062c5bc4SJason Schmidlapp if (mx->kind != PTHREAD_MUTEX_RECURSIVE 104062c5bc4SJason Schmidlapp || 0 == --mx->recursive_count) 105062c5bc4SJason Schmidlapp { 106*a12978ccSJeremy Soller mx->ownerThread = NULL; 107062c5bc4SJason Schmidlapp 108062c5bc4SJason Schmidlapp if (PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0) < 0) 109062c5bc4SJason Schmidlapp { 110062c5bc4SJason Schmidlapp if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK) 111062c5bc4SJason Schmidlapp { 112062c5bc4SJason Schmidlapp result = EINVAL; 113062c5bc4SJason Schmidlapp } 114062c5bc4SJason Schmidlapp 115062c5bc4SJason Schmidlapp } 116062c5bc4SJason Schmidlapp } 117062c5bc4SJason Schmidlapp } 118062c5bc4SJason Schmidlapp else 119062c5bc4SJason Schmidlapp { 120062c5bc4SJason Schmidlapp result = EPERM; 121062c5bc4SJason Schmidlapp } 122062c5bc4SJason Schmidlapp } 123062c5bc4SJason Schmidlapp } 124062c5bc4SJason Schmidlapp else 125062c5bc4SJason Schmidlapp { 126062c5bc4SJason Schmidlapp result = EINVAL; 127062c5bc4SJason Schmidlapp } 128062c5bc4SJason Schmidlapp 129062c5bc4SJason Schmidlapp return (result); 130062c5bc4SJason Schmidlapp } 131