1998-04-29 09:59:34 +00:00
/*
* Copyright ( c ) 1997 John Birrell < jb @ cimlogic . com . au > .
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement :
* This product includes software developed by John Birrell .
* 4. Neither the name of the author nor the names of any co - contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1999-08-05 12:15:30 +00:00
* ARE DISCLAIMED . IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1998-04-29 09:59:34 +00:00
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*
1999-08-28 00:22:10 +00:00
* $ FreeBSD $
1998-04-29 09:59:34 +00:00
*
*/
2002-03-29 22:43:43 +00:00
# include <stdlib.h>
1998-04-29 09:59:34 +00:00
# include <stdio.h>
2002-03-29 22:43:43 +00:00
# include <string.h>
1998-04-29 09:59:34 +00:00
# include <sched.h>
# include <pthread.h>
2002-03-29 22:43:43 +00:00
# include <unistd.h>
# include <libc_private.h>
1998-04-29 09:59:34 +00:00
2002-03-29 22:43:43 +00:00
# include "pthread_private.h"
1998-06-09 23:13:10 +00:00
2003-03-26 04:02:24 +00:00
void
_spinunlock ( spinlock_t * lck )
{
lck - > access_lock = 0 ;
}
1998-04-29 09:59:34 +00:00
/*
* Lock a location for the running thread . Yield to allow other
* threads to run if this thread is blocked because the lock is
* not available . Note that this function does not sleep . It
* assumes that the lock will be available very soon .
*/
void
1998-06-09 23:13:10 +00:00
_spinlock ( spinlock_t * lck )
1998-04-29 09:59:34 +00:00
{
2001-01-24 13:03:38 +00:00
struct pthread * curthread = _get_curthread ( ) ;
1998-06-09 23:13:10 +00:00
/*
* Try to grab the lock and loop if another thread grabs
* it before we do .
*/
while ( _atomic_lock ( & lck - > access_lock ) ) {
1999-03-23 05:07:56 +00:00
/* Block the thread until the lock. */
2001-01-24 13:03:38 +00:00
curthread - > data . spinlock = lck ;
1999-03-23 05:07:56 +00:00
_thread_kern_sched_state ( PS_SPINBLOCK , __FILE__ , __LINE__ ) ;
1998-06-09 23:13:10 +00:00
}
1998-04-29 09:59:34 +00:00
1998-06-09 23:13:10 +00:00
/* The running thread now owns the lock: */
2001-01-24 13:03:38 +00:00
lck - > lock_owner = ( long ) curthread ;
1998-06-09 23:13:10 +00:00
}
/*
* Lock a location for the running thread . Yield to allow other
* threads to run if this thread is blocked because the lock is
* not available . Note that this function does not sleep . It
* assumes that the lock will be available very soon .
*
* This function checks if the running thread has already locked the
* location , warns if this occurs and creates a thread dump before
* returning .
*/
void
_spinlock_debug ( spinlock_t * lck , char * fname , int lineno )
{
2001-01-24 13:03:38 +00:00
struct pthread * curthread = _get_curthread ( ) ;
1999-03-23 05:07:56 +00:00
int cnt = 0 ;
1998-04-29 09:59:34 +00:00
/*
* Try to grab the lock and loop if another thread grabs
* it before we do .
*/
1998-06-09 23:13:10 +00:00
while ( _atomic_lock ( & lck - > access_lock ) ) {
1999-03-23 05:07:56 +00:00
cnt + + ;
if ( cnt > 100 ) {
1998-06-09 23:13:10 +00:00
char str [ 256 ] ;
2002-05-24 04:32:28 +00:00
snprintf ( str , sizeof ( str ) , " %s - Warning: Thread %p attempted to lock %p from %s (%d) was left locked from %s (%d) \n " , getprogname ( ) , curthread , lck , fname , lineno , lck - > fname , lck - > lineno ) ;
2001-01-24 13:03:38 +00:00
__sys_write ( 2 , str , strlen ( str ) ) ;
Simplify sytem call renaming. Instead of _foo() <-- _libc_foo <-- foo(),
just use _foo() <-- foo(). In the case of a libpthread that doesn't do
call conversion (such as linuxthreads and our upcoming libpthread), this
is adequate. In the case of libc_r, we still need three names, which are
now _thread_sys_foo() <-- _foo() <-- foo().
Convert all internal libc usage of: aio_suspend(), close(), fsync(), msync(),
nanosleep(), open(), fcntl(), read(), and write() to _foo() instead of foo().
Remove all internal libc usage of: creat(), pause(), sleep(), system(),
tcdrain(), wait(), and waitpid().
Make thread cancellation fully POSIX-compliant.
Suggested by: deischen
2000-01-27 23:07:25 +00:00
__sleep ( 1 ) ;
1999-03-23 05:07:56 +00:00
cnt = 0 ;
1998-06-09 23:13:10 +00:00
}
1999-03-23 05:07:56 +00:00
/* Block the thread until the lock. */
2001-01-24 13:03:38 +00:00
curthread - > data . spinlock = lck ;
1999-03-23 05:07:56 +00:00
_thread_kern_sched_state ( PS_SPINBLOCK , fname , lineno ) ;
1998-06-09 23:13:10 +00:00
}
/* The running thread now owns the lock: */
2001-01-24 13:03:38 +00:00
lck - > lock_owner = ( long ) curthread ;
1998-06-09 23:13:10 +00:00
lck - > fname = fname ;
lck - > lineno = lineno ;
1998-04-29 09:59:34 +00:00
}