123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /* Linuxthreads - a simple clone()-based implementation of Posix */
- /* threads for Linux. */
- /* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
- /* */
- /* This program is free software; you can redistribute it and/or */
- /* modify it under the terms of the GNU Library General Public License */
- /* as published by the Free Software Foundation; either version 2 */
- /* of the License, or (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU Library General Public License for more details. */
- #if defined(TEST_FOR_COMPARE_AND_SWAP)
- extern int __pthread_has_cas;
- extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval,
- int * spinlock);
- static inline int compare_and_swap(long * ptr, long oldval, long newval,
- int * spinlock)
- {
- if (__builtin_expect (__pthread_has_cas, 1))
- return __compare_and_swap(ptr, oldval, newval);
- else
- return __pthread_compare_and_swap(ptr, oldval, newval, spinlock);
- }
- #elif defined(HAS_COMPARE_AND_SWAP)
- static inline int compare_and_swap(long * ptr, long oldval, long newval,
- int * spinlock)
- {
- return __compare_and_swap(ptr, oldval, newval);
- }
- #else
- extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval,
- int * spinlock);
- static inline int compare_and_swap(long * ptr, long oldval, long newval,
- int * spinlock)
- {
- return __pthread_compare_and_swap(ptr, oldval, newval, spinlock);
- }
- #endif
- /* Internal locks */
- extern void internal_function __pthread_lock(struct _pthread_fastlock * lock,
- pthread_descr self);
- extern void internal_function __pthread_unlock(struct _pthread_fastlock *lock);
- static inline void __pthread_init_lock(struct _pthread_fastlock * lock)
- {
- lock->__status = 0;
- lock->__spinlock = 0;
- }
- static inline int __pthread_trylock (struct _pthread_fastlock * lock)
- {
- long oldstatus;
- do {
- oldstatus = lock->__status;
- if (oldstatus != 0) return EBUSY;
- } while(! compare_and_swap(&lock->__status, 0, 1, &lock->__spinlock));
- return 0;
- }
- #define LOCK_INITIALIZER {0, 0}
- /* Operations on pthread_atomic, which is defined in internals.h */
- static inline long atomic_increment(struct pthread_atomic *pa)
- {
- long oldval;
- do {
- oldval = pa->p_count;
- } while (!compare_and_swap(&pa->p_count, oldval, oldval + 1, &pa->p_spinlock));
- return oldval;
- }
- static inline long atomic_decrement(struct pthread_atomic *pa)
- {
- long oldval;
- do {
- oldval = pa->p_count;
- } while (!compare_and_swap(&pa->p_count, oldval, oldval - 1, &pa->p_spinlock));
- return oldval;
- }
- #define ATOMIC_INITIALIZER { 0, 0 }
|