Changeset e0f93e0


Ignore:
Timestamp:
Jul 30, 2020, 2:57:36 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
f00b26d4
Parents:
22ddade
Message:

Added single_sem type, which effectively extends park/unpark logic for cases where extra unparks would have been acceptable.

File:
1 edited

Legend:

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

    r22ddade re0f93e0  
    164164
    165165        #undef CHECKED
     166
     167        struct $thread;
     168        extern void park( __cfaabi_dbg_ctx_param );
     169        extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 );
     170        static inline struct $thread * active_thread ();
     171
     172        // Semaphore which only supports a single thread
     173        struct single_sem {
     174                struct $thread * volatile ptr;
     175        };
     176
     177        static inline {
     178                void  ?{}(single_sem & this) {
     179                        this.ptr = 0p;
     180                }
     181
     182                void ^?{}(single_sem & this) {}
     183
     184                bool wait(single_sem & this) {
     185                        for() {
     186                                struct $thread * expected = this.ptr;
     187                                if(expected == 1p) {
     188                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     189                                                return false;
     190                                        }
     191                                }
     192                                else {
     193                                        /* paranoid */ verify( expected == 0p );
     194                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     195                                                park( __cfaabi_dbg_ctx );
     196                                                return true;
     197                                        }
     198                                }
     199
     200                        }
     201                }
     202
     203                bool post(single_sem & this) {
     204                        for() {
     205                                struct $thread * expected = this.ptr;
     206                                if(expected == 1p) return false;
     207                                if(expected == 0p) {
     208                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     209                                                return false;
     210                                        }
     211                                }
     212                                else {
     213                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     214                                                unpark( expected __cfaabi_dbg_ctx2 );
     215                                                return true;
     216                                        }
     217                                }
     218                        }
     219                }
     220        }
    166221#endif
Note: See TracChangeset for help on using the changeset viewer.