Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/locks.hfa

    re3fea42 r6ec07e5  
    5454
    5555                #ifdef __CFA_DEBUG__
    56                         void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]);
     56                        void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]);
    5757                #else
    58                         #define __cfaabi_dbg_record(x, y)
     58                        #define __cfaabi_dbg_record_lock(x, y)
    5959                #endif
    6060        }
    61 
    62         extern void yield( unsigned int );
    6361
    6462        static inline void ?{}( __spinlock_t & this ) {
     
    6866        // Lock the spinlock, return false if already acquired
    6967        static inline bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
     68                disable_interrupts();
    7069                bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
    7170                if( result ) {
    72                         disable_interrupts();
    73                         __cfaabi_dbg_record( this, caller );
     71                        __cfaabi_dbg_record_lock( this, caller );
     72                } else {
     73                        enable_interrupts_noPoll();
    7474                }
    7575                return result;
     
    8383                #endif
    8484
     85                disable_interrupts();
    8586                for ( unsigned int i = 1;; i += 1 ) {
    8687                        if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
     
    9899                        #endif
    99100                }
    100                 disable_interrupts();
    101                 __cfaabi_dbg_record( this, caller );
     101                __cfaabi_dbg_record_lock( this, caller );
    102102        }
    103103
    104104        static inline void unlock( __spinlock_t & this ) {
     105                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    105106                enable_interrupts_noPoll();
    106                 __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    107107        }
    108108
     
    112112        #endif
    113113
     114        extern "C" {
     115                char * strerror(int);
     116        }
     117        #define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); }
     118
    114119        struct __bin_sem_t {
    115                 bool                    signaled;
    116120                pthread_mutex_t         lock;
    117121                pthread_cond_t          cond;
     122                int                     val;
    118123        };
    119124
    120125        static inline void ?{}(__bin_sem_t & this) with( this ) {
    121                 signaled = false;
    122                 pthread_mutex_init(&lock, NULL);
    123                 pthread_cond_init (&cond, NULL);
     126                // Create the mutex with error checking
     127                pthread_mutexattr_t mattr;
     128                pthread_mutexattr_init( &mattr );
     129                pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP);
     130                pthread_mutex_init(&lock, &mattr);
     131
     132                pthread_cond_init (&cond, 0p);
     133                val = 0;
    124134        }
    125135
    126136        static inline void ^?{}(__bin_sem_t & this) with( this ) {
    127                 pthread_mutex_destroy(&lock);
    128                 pthread_cond_destroy (&cond);
     137                CHECKED( pthread_mutex_destroy(&lock) );
     138                CHECKED( pthread_cond_destroy (&cond) );
    129139        }
    130140
    131141        static inline void wait(__bin_sem_t & this) with( this ) {
    132142                verify(__cfaabi_dbg_in_kernel());
    133                 pthread_mutex_lock(&lock);
    134                         if(!signaled) {   // this must be a loop, not if!
     143                CHECKED( pthread_mutex_lock(&lock) );
     144                        while(val < 1) {
    135145                                pthread_cond_wait(&cond, &lock);
    136146                        }
    137                         signaled = false;
    138                 pthread_mutex_unlock(&lock);
     147                        val -= 1;
     148                CHECKED( pthread_mutex_unlock(&lock) );
    139149        }
    140150
    141         static inline void post(__bin_sem_t & this) with( this ) {
    142                 verify(__cfaabi_dbg_in_kernel());
     151        static inline bool post(__bin_sem_t & this) with( this ) {
     152                bool needs_signal = false;
    143153
    144                 pthread_mutex_lock(&lock);
    145                         bool needs_signal = !signaled;
    146                         signaled = true;
    147                 pthread_mutex_unlock(&lock);
     154                CHECKED( pthread_mutex_lock(&lock) );
     155                        if(val < 1) {
     156                                val += 1;
     157                                pthread_cond_signal(&cond);
     158                                needs_signal = true;
     159                        }
     160                CHECKED( pthread_mutex_unlock(&lock) );
    148161
    149                 if (needs_signal)
    150                         pthread_cond_signal(&cond);
     162                return needs_signal;
    151163        }
     164
     165        #undef CHECKED
    152166#endif
Note: See TracChangeset for help on using the changeset viewer.