Ignore:
Timestamp:
Mar 7, 2023, 3:10:35 PM (16 months ago)
Author:
caparson <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
9155026
Parents:
ab81e3b
Message:

some actor cleanup/optimizations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/actor.hfa

    rab81e3b re23169b  
    371371
    372372// this is a static field of executor but have to forward decl for get_next_ticket
    373 static unsigned long int __next_ticket = 0;
    374 
    375 static inline unsigned long int __get_next_ticket( executor & this ) with(this) {
    376     unsigned long int temp = __atomic_fetch_add( &__next_ticket, 1, __ATOMIC_SEQ_CST) % nrqueues;
     373static size_t __next_ticket = 0;
     374
     375static inline size_t __get_next_ticket( executor & this ) with(this) {
     376    #ifdef __CFA_DEBUG__
     377    size_t temp = __atomic_fetch_add( &__next_ticket, 1, __ATOMIC_SEQ_CST) % nrqueues;
    377378
    378379    // reserve MAX for dead actors
    379     if ( temp == MAX ) temp = __atomic_fetch_add( &__next_ticket, 1, __ATOMIC_SEQ_CST) % nrqueues;
     380    if ( unlikely( temp == MAX ) ) temp = __atomic_fetch_add( &__next_ticket, 1, __ATOMIC_SEQ_CST) % nrqueues;
    380381    return temp;
     382    #else
     383    return __atomic_fetch_add( &__next_ticket, 1, __ATOMIC_RELAXED) % nrqueues;
     384    #endif
    381385} // tickets
    382386
     
    384388static executor * __actor_executor_ = 0p;
    385389static bool __actor_executor_passed = false;            // was an executor passed to start_actor_system
    386 static unsigned long int __num_actors_ = 0;                             // number of actor objects in system
     390static size_t __num_actors_ = 0;                                // number of actor objects in system
    387391static struct thread$ * __actor_executor_thd = 0p;              // used to wake executor after actors finish
    388392struct actor {
    389     unsigned long int ticket;                           // executor-queue handle
     393    size_t ticket;                              // executor-queue handle
    390394    Allocation allocation_;                                         // allocation action
    391395};
    392396
    393 static inline void ?{}( actor & this ) {
     397static inline void ?{}( actor & this ) with(this) {
    394398    // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive
    395399    // member must be called to end it
    396400    verifyf( __actor_executor_, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );
    397     this.allocation_ = Nodelete;
    398     this.ticket = __get_next_ticket( *__actor_executor_ );
    399     __atomic_fetch_add( &__num_actors_, 1, __ATOMIC_SEQ_CST );
     401    allocation_ = Nodelete;
     402    ticket = __get_next_ticket( *__actor_executor_ );
     403    __atomic_fetch_add( &__num_actors_, 1, __ATOMIC_RELAXED );
    400404    #ifdef STATS
    401405    __atomic_fetch_add( &__num_actors_stats, 1, __ATOMIC_SEQ_CST );
     
    418422        }
    419423
    420         if ( unlikely( __atomic_add_fetch( &__num_actors_, -1, __ATOMIC_SEQ_CST ) == 0 ) ) { // all actors have terminated
     424        if ( unlikely( __atomic_add_fetch( &__num_actors_, -1, __ATOMIC_RELAXED ) == 0 ) ) { // all actors have terminated
    421425            unpark( __actor_executor_thd );
    422426        }
     
    430434static inline void ?{}( message & this ) { this.allocation_ = Nodelete; }
    431435static inline void ?{}( message & this, Allocation allocation ) {
    432     this.allocation_ = allocation;
     436    memcpy( &this.allocation_, &allocation, sizeof(allocation) ); // optimization to elide ctor
    433437    verifyf( this.allocation_ != Finished, "The Finished Allocation status is not supported for message types.\n");
    434438}
     
    449453
    450454static inline void deliver_request( request & this ) {
    451     Allocation actor_allocation = this.fn( *this.receiver, *this.msg );
    452     this.receiver->allocation_ = actor_allocation;
     455    this.receiver->allocation_ = this.fn( *this.receiver, *this.msg );
    453456    check_actor( *this.receiver );
    454457    check_message( *this.msg );
     
    563566    unsigned int empty_count = 0;
    564567    request & req;
    565     unsigned int curr_idx;
    566568    work_queue * curr_work_queue;
    567569
    568570    Exit:
    569571    for ( unsigned int i = 0;; i = (i + 1) % range ) { // cycle through set of request buffers
    570         curr_idx = i + start;
    571         curr_work_queue = request_queues[curr_idx];
     572        curr_work_queue = request_queues[i + start];
    572573       
    573574        // check if queue is empty before trying to gulp it
Note: See TracChangeset for help on using the changeset viewer.