Ignore:
File:
1 edited

Legend:

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

    r6ec07e5 re3fea42  
    5454
    5555                #ifdef __CFA_DEBUG__
    56                         void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]);
     56                        void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]);
    5757                #else
    58                         #define __cfaabi_dbg_record_lock(x, y)
     58                        #define __cfaabi_dbg_record(x, y)
    5959                #endif
    6060        }
     61
     62        extern void yield( unsigned int );
    6163
    6264        static inline void ?{}( __spinlock_t & this ) {
     
    6668        // Lock the spinlock, return false if already acquired
    6769        static inline bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
    68                 disable_interrupts();
    6970                bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
    7071                if( result ) {
    71                         __cfaabi_dbg_record_lock( this, caller );
    72                 } else {
    73                         enable_interrupts_noPoll();
     72                        disable_interrupts();
     73                        __cfaabi_dbg_record( this, caller );
    7474                }
    7575                return result;
     
    8383                #endif
    8484
    85                 disable_interrupts();
    8685                for ( unsigned int i = 1;; i += 1 ) {
    8786                        if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
     
    9998                        #endif
    10099                }
    101                 __cfaabi_dbg_record_lock( this, caller );
     100                disable_interrupts();
     101                __cfaabi_dbg_record( this, caller );
    102102        }
    103103
    104104        static inline void unlock( __spinlock_t & this ) {
     105                enable_interrupts_noPoll();
    105106                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    106                 enable_interrupts_noPoll();
    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 
    119114        struct __bin_sem_t {
     115                bool                    signaled;
    120116                pthread_mutex_t         lock;
    121117                pthread_cond_t          cond;
    122                 int                     val;
    123118        };
    124119
    125120        static inline void ?{}(__bin_sem_t & this) with( this ) {
    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;
     121                signaled = false;
     122                pthread_mutex_init(&lock, NULL);
     123                pthread_cond_init (&cond, NULL);
    134124        }
    135125
    136126        static inline void ^?{}(__bin_sem_t & this) with( this ) {
    137                 CHECKED( pthread_mutex_destroy(&lock) );
    138                 CHECKED( pthread_cond_destroy (&cond) );
     127                pthread_mutex_destroy(&lock);
     128                pthread_cond_destroy (&cond);
    139129        }
    140130
    141131        static inline void wait(__bin_sem_t & this) with( this ) {
    142132                verify(__cfaabi_dbg_in_kernel());
    143                 CHECKED( pthread_mutex_lock(&lock) );
    144                         while(val < 1) {
     133                pthread_mutex_lock(&lock);
     134                        if(!signaled) {   // this must be a loop, not if!
    145135                                pthread_cond_wait(&cond, &lock);
    146136                        }
    147                         val -= 1;
    148                 CHECKED( pthread_mutex_unlock(&lock) );
     137                        signaled = false;
     138                pthread_mutex_unlock(&lock);
    149139        }
    150140
    151         static inline bool post(__bin_sem_t & this) with( this ) {
    152                 bool needs_signal = false;
     141        static inline void post(__bin_sem_t & this) with( this ) {
     142                verify(__cfaabi_dbg_in_kernel());
    153143
    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) );
     144                pthread_mutex_lock(&lock);
     145                        bool needs_signal = !signaled;
     146                        signaled = true;
     147                pthread_mutex_unlock(&lock);
    161148
    162                 return needs_signal;
     149                if (needs_signal)
     150                        pthread_cond_signal(&cond);
    163151        }
    164 
    165         #undef CHECKED
    166152#endif
Note: See TracChangeset for help on using the changeset viewer.