Ignore:
Timestamp:
Nov 20, 2017, 12:12:34 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
fdd3786
Parents:
b7f8cb44
Message:

Added generic containers for runtime.
Moved some internal code to bits folder.
consistently used cforall instead of CFORALL define.

Location:
src/libcfa/concurrency
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/invoke.h

    rb7f8cb44 r0cf5b79  
    1414//
    1515
     16#include "bits/containers.h"
    1617#include "bits/defs.h"
    1718#include "bits/locks.h"
    1819
    19 #ifdef __CFORALL__
     20#ifdef __cforall
    2021extern "C" {
    2122#endif
     
    2526#define _INVOKE_H_
    2627
    27         typedef void (*fptr_t)();
    28         typedef int_fast16_t __lock_size_t;
    29 
    30         struct __thread_queue_t {
    31                 struct thread_desc * head;
    32                 struct thread_desc ** tail;
    33         };
    34 
    35         struct __condition_stack_t {
    36                 struct __condition_criterion_t * top;
    37         };
    38 
    39         #ifdef __CFORALL__
     28        #ifdef __cforall
    4029        extern "Cforall" {
    41                 void ?{}( struct __thread_queue_t & );
    42                 void append( struct __thread_queue_t &, struct thread_desc * );
    43                 struct thread_desc * pop_head( struct __thread_queue_t & );
    44                 struct thread_desc * remove( struct __thread_queue_t &, struct thread_desc ** );
    45 
    46                 void ?{}( struct __condition_stack_t & );
    47                 void push( struct __condition_stack_t &, struct __condition_criterion_t * );
    48                 struct __condition_criterion_t * pop( struct __condition_stack_t & );
     30                static inline struct thread_desc             * & get_next( struct thread_desc             & this );
     31                static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    4932        }
    5033        #endif
     
    10083
    10184                // list of acceptable functions, null if any
    102                 struct __acceptable_t * clauses;
    103 
    104                 // number of acceptable functions
    105                 __lock_size_t size;
     85                __small_array_t(struct __acceptable_t) __cfa_anonymous_object;
    10686        };
    10787
     
    11494
    11595                // queue of threads that are blocked waiting for the monitor
    116                 struct __thread_queue_t entry_queue;
     96                __queue_t(struct thread_desc) entry_queue;
    11797
    11898                // stack of conditions to run next once we exit the monitor
    119                 struct __condition_stack_t signal_stack;
     99                __stack_t(struct __condition_criterion_t) signal_stack;
    120100
    121101                // monitor routines can be called recursively, we need to keep track of that
     
    131111        struct __monitor_group_t {
    132112                // currently held monitors
    133                 struct monitor_desc ** list;
    134 
    135                 // number of currently held monitors
    136                 __lock_size_t size;
     113                __small_array_t(monitor_desc*) __cfa_anonymous_object;
    137114
    138115                // last function that acquired monitors
     
    159136     };
    160137
    161      #ifdef __CFORALL__
     138     #ifdef __cforall
    162139     extern "Cforall" {
    163                 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {
    164                         return this.list[index];
     140                static inline thread_desc * & get_next( thread_desc & this ) {
     141                        return this.next;
     142                }
     143
     144                static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
     145
     146                static inline void ?{}(__monitor_group_t & this) {
     147                        (this.data){NULL};
     148                        (this.size){0};
     149                        (this.func){NULL};
     150                }
     151
     152                static inline void ?{}(__monitor_group_t & this, struct monitor_desc ** data, __lock_size_t size, fptr_t func) {
     153                        (this.data){data};
     154                        (this.size){size};
     155                        (this.func){func};
    165156                }
    166157
    167158                static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {
    168                         if( (lhs.list != 0) != (rhs.list != 0) ) return false;
     159                        if( (lhs.data != 0) != (rhs.data != 0) ) return false;
    169160                        if( lhs.size != rhs.size ) return false;
    170161                        if( lhs.func != rhs.func ) return false;
     
    177168
    178169                        return true;
     170                }
     171
     172                static inline void ?=?(__monitor_group_t & lhs, const __monitor_group_t & rhs) {
     173                        lhs.data = rhs.data;
     174                        lhs.size = rhs.size;
     175                        lhs.func = rhs.func;
    179176                }
    180177        }
     
    210207#endif //_INVOKE_PRIVATE_H_
    211208#endif //! defined(__CFA_INVOKE_PRIVATE__)
    212 #ifdef __CFORALL__
     209#ifdef __cforall
    213210}
    214211#endif
  • src/libcfa/concurrency/kernel

    rb7f8cb44 r0cf5b79  
    2626//-----------------------------------------------------------------------------
    2727// Locks
    28 // // Lock the spinlock, spin if already acquired
    29 // void lock      ( spinlock * DEBUG_CTX_PARAM2 );
    30 
    31 // // Lock the spinlock, yield repeatedly if already acquired
    32 // void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
    33 
    34 // // Lock the spinlock, return false if already acquired
    35 // bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
    36 
    37 // // Unlock the spinlock
    38 // void unlock    ( spinlock * );
    39 
    4028struct semaphore {
    4129        __spinlock_t lock;
    4230        int count;
    43         __thread_queue_t waiting;
     31        __queue_t(thread_desc) waiting;
    4432};
    4533
     
    5745
    5846        // Ready queue for threads
    59         __thread_queue_t ready_queue;
     47        __queue_t(thread_desc) ready_queue;
    6048
    6149        // Preemption rate on this cluster
  • src/libcfa/concurrency/kernel.c

    rb7f8cb44 r0cf5b79  
    164164
    165165void ?{}(cluster & this) {
    166         ( this.ready_queue ){};
     166        (this.ready_queue){};
    167167        ( this.ready_queue_lock ){};
    168168
     
    611611}
    612612
    613 //-----------------------------------------------------------------------------
    614 // Queues
    615 void ?{}( __thread_queue_t & this ) {
    616         this.head = NULL;
    617         this.tail = &this.head;
    618 }
    619 
    620 void append( __thread_queue_t & this, thread_desc * t ) {
    621         verify(this.tail != NULL);
    622         *this.tail = t;
    623         this.tail = &t->next;
    624 }
    625 
    626 thread_desc * pop_head( __thread_queue_t & this ) {
    627         thread_desc * head = this.head;
    628         if( head ) {
    629                 this.head = head->next;
    630                 if( !head->next ) {
    631                         this.tail = &this.head;
    632                 }
    633                 head->next = NULL;
    634         }
    635         return head;
    636 }
    637 
    638 thread_desc * remove( __thread_queue_t & this, thread_desc ** it ) {
    639         thread_desc * thrd = *it;
    640         verify( thrd );
    641 
    642         (*it) = thrd->next;
    643 
    644         if( this.tail == &thrd->next ) {
    645                 this.tail = it;
    646         }
    647 
    648         thrd->next = NULL;
    649 
    650         verify( (this.head == NULL) == (&this.head == this.tail) );
    651         verify( *this.tail == NULL );
    652         return thrd;
    653 }
    654 
    655 void ?{}( __condition_stack_t & this ) {
    656         this.top = NULL;
    657 }
    658 
    659 void push( __condition_stack_t & this, __condition_criterion_t * t ) {
    660         verify( !t->next );
    661         t->next = this.top;
    662         this.top = t;
    663 }
    664 
    665 __condition_criterion_t * pop( __condition_stack_t & this ) {
    666         __condition_criterion_t * top = this.top;
    667         if( top ) {
    668                 this.top = top->next;
    669                 top->next = NULL;
    670         }
    671         return top;
    672 }
    673 
    674613// Local Variables: //
    675614// mode: c //
  • src/libcfa/concurrency/monitor

    rb7f8cb44 r0cf5b79  
    3434        this.recursion     = 0;
    3535        this.mask.accepted = NULL;
    36         this.mask.clauses  = NULL;
     36        this.mask.data     = NULL;
    3737        this.mask.size     = 0;
    3838        this.dtor_node     = NULL;
     
    4040
    4141struct monitor_guard_t {
    42         monitor_desc ** m;
    43         __lock_size_t   count;
    44         monitor_desc ** prev_mntrs;
    45         __lock_size_t   prev_count;
    46         fptr_t          prev_func;
     42        monitor_desc **         m;
     43        __lock_size_t           count;
     44        __monitor_group_t prev;
    4745};
    4846
     
    5149
    5250struct monitor_dtor_guard_t {
    53         monitor_desc * m;
    54         monitor_desc ** prev_mntrs;
    55         __lock_size_t   prev_count;
    56         fptr_t          prev_func;
     51        monitor_desc *    m;
     52        __monitor_group_t prev;
    5753};
    5854
     
    8379};
    8480
     81static inline __condition_criterion_t * & get_next( __condition_criterion_t & this ) {
     82        return this.next;
     83}
     84
    8585struct __condition_node_t {
    8686        // Thread that needs to be woken when all criteria are met
     
    100100};
    101101
    102 struct __condition_blocked_queue_t {
    103         __condition_node_t * head;
    104         __condition_node_t ** tail;
    105 };
     102static inline __condition_node_t * & get_next( __condition_node_t & this ) {
     103        return this.next;
     104}
    106105
    107106void ?{}(__condition_node_t & this, thread_desc * waiting_thread, __lock_size_t count, uintptr_t user_info );
     
    109108void ?{}(__condition_criterion_t & this, monitor_desc * target, __condition_node_t * owner );
    110109
    111 void ?{}( __condition_blocked_queue_t & );
    112 void append( __condition_blocked_queue_t &, __condition_node_t * );
    113 __condition_node_t * pop_head( __condition_blocked_queue_t & );
    114 
    115110struct condition {
    116111        // Link list which contains the blocked threads as-well as the information needed to unblock them
    117         __condition_blocked_queue_t blocked;
     112        __queue_t(__condition_node_t) blocked;
    118113
    119114        // Array of monitor pointers (Monitors are NOT contiguous in memory)
  • src/libcfa/concurrency/monitor.c

    rb7f8cb44 r0cf5b79  
    280280static inline void enter( __monitor_group_t monitors ) {
    281281        for( __lock_size_t i = 0; i < monitors.size; i++) {
    282                 __enter_monitor_desc( monitors.list[i], monitors );
     282                __enter_monitor_desc( monitors[i], monitors );
    283283        }
    284284}
     
    303303
    304304        // Save previous thread context
    305         this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     305        this.prev = this_thread->monitors;
    306306
    307307        // Update thread context (needed for conditions)
    308         this_thread->monitors.[list, size, func] = [m, count, func];
     308        (this_thread->monitors){m, count, func};
    309309
    310310        // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);
     
    328328
    329329        // Restore thread context
    330         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     330        this_thread->monitors = this.prev;
    331331}
    332332
     
    338338
    339339        // Save previous thread context
    340         this.[prev_mntrs, prev_count, prev_func] = this_thread->monitors.[list, size, func];
     340        this.prev = this_thread->monitors;
    341341
    342342        // Update thread context (needed for conditions)
    343         this_thread->monitors.[list, size, func] = [m, 1, func];
     343        (this_thread->monitors){m, 1, func};
    344344
    345345        __enter_monitor_dtor( this.m, func );
     
    352352
    353353        // Restore thread context
    354         this_thread->monitors.[list, size, func] = this.[prev_mntrs, prev_count, prev_func];
     354        this_thread->monitors = this.prev;
    355355}
    356356
     
    437437
    438438                for(int i = 0; i < this.monitor_count; i++) {
    439                         if ( this.monitors[i] != this_thrd->monitors.list[i] ) {
    440                                 abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors.list[i] );
     439                        if ( this.monitors[i] != this_thrd->monitors[i] ) {
     440                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors[i] );
    441441                        }
    442442                }
     
    510510                "Possible cause is not checking if the condition is empty before reading stored data."
    511511        );
    512         return this.blocked.head->user_info;
     512        return ((typeof(this.blocked.head))this.blocked.head)->user_info;
    513513}
    514514
     
    554554                if( next ) {
    555555                        *mask.accepted = index;
    556                         if( mask.clauses[index].is_dtor ) {
     556                        __acceptable_t& accepted = mask[index];
     557                        if( accepted.is_dtor ) {
    557558                                LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : dtor already there\n");
    558                                 verifyf( mask.clauses[index].size == 1        , "ERROR: Accepted dtor has more than 1 mutex parameter." );
    559 
    560                                 monitor_desc * mon2dtor = mask.clauses[index].list[0];
     559                                verifyf( accepted.size == 1, "ERROR: Accepted dtor has more than 1 mutex parameter." );
     560
     561                                monitor_desc * mon2dtor = accepted[0];
    561562                                verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." );
    562563
     
    596597
    597598                        LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);
    598 
    599599                        return;
    600600                }
     
    671671static inline void reset_mask( monitor_desc * this ) {
    672672        this->mask.accepted = NULL;
    673         this->mask.clauses = NULL;
     673        this->mask.data = NULL;
    674674        this->mask.size = 0;
    675675}
     
    697697
    698698static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group ) {
    699         __acceptable_t * it = this->mask.clauses; // Optim
     699        __acceptable_t * it = this->mask.data; // Optim
    700700        __lock_size_t count = this->mask.size;
    701701
     
    820820        if( !this.monitors ) {
    821821                // LIB_DEBUG_PRINT_SAFE("Branding\n");
    822                 assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
     822                assertf( thrd->monitors.data != NULL, "No current monitor to brand condition %p", thrd->monitors.data );
    823823                this.monitor_count = thrd->monitors.size;
    824824
    825825                this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) );
    826826                for( int i = 0; i < this.monitor_count; i++ ) {
    827                         this.monitors[i] = thrd->monitors.list[i];
     827                        this.monitors[i] = thrd->monitors[i];
    828828                }
    829829        }
     
    832832static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc * monitors [], __lock_size_t count ) {
    833833
    834         __thread_queue_t & entry_queue = monitors[0]->entry_queue;
     834        __queue_t(thread_desc) & entry_queue = monitors[0]->entry_queue;
    835835
    836836        // For each thread in the entry-queue
     
    841841                // For each acceptable check if it matches
    842842                int i = 0;
    843                 __acceptable_t * end = mask.clauses + mask.size;
    844                 for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) {
     843                __acceptable_t * end   = end  (mask);
     844                __acceptable_t * begin = begin(mask);
     845                for( __acceptable_t * it = begin; it != end; it++, i++ ) {
    845846                        // Check if we have a match
    846847                        if( *it == (*thrd_it)->monitors ) {
     
    872873        __lock_size_t max = 0;
    873874        for( __lock_size_t i = 0; i < mask.size; i++ ) {
    874                 max += mask.clauses[i].size;
     875                __acceptable_t & accepted = mask[i];
     876                max += accepted.size;
    875877        }
    876878        return max;
     
    880882        __lock_size_t size = 0;
    881883        for( __lock_size_t i = 0; i < mask.size; i++ ) {
    882                 __libcfa_small_sort( mask.clauses[i].list, mask.clauses[i].size );
    883                 for( __lock_size_t j = 0; j < mask.clauses[i].size; j++) {
    884                         insert_unique( storage, size, mask.clauses[i].list[j] );
     884                __acceptable_t & accepted = mask[i];
     885                __libcfa_small_sort( accepted.data, accepted.size );
     886                for( __lock_size_t j = 0; j < accepted.size; j++) {
     887                        insert_unique( storage, size, accepted[j] );
    885888                }
    886889        }
     
    888891        __libcfa_small_sort( storage, size );
    889892        return size;
    890 }
    891 
    892 void ?{}( __condition_blocked_queue_t & this ) {
    893         this.head = NULL;
    894         this.tail = &this.head;
    895 }
    896 
    897 void append( __condition_blocked_queue_t & this, __condition_node_t * c ) {
    898         verify(this.tail != NULL);
    899         *this.tail = c;
    900         this.tail = &c->next;
    901 }
    902 
    903 __condition_node_t * pop_head( __condition_blocked_queue_t & this ) {
    904         __condition_node_t * head = this.head;
    905         if( head ) {
    906                 this.head = head->next;
    907                 if( !head->next ) {
    908                         this.tail = &this.head;
    909                 }
    910                 head->next = NULL;
    911         }
    912         return head;
    913893}
    914894
Note: See TracChangeset for help on using the changeset viewer.