Changeset 3e3f236 for libcfa/src


Ignore:
Timestamp:
Dec 10, 2020, 4:00:29 PM (5 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
97aca3df, b3a0df6
Parents:
6a45bd78 (diff), 297cf18 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r6a45bd78 r3e3f236  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Jun  1 13:35:33 2020
    14 ## Update Count     : 248
     13## Last Modified On : Wed Dec  9 22:46:14 2020
     14## Update Count     : 250
    1515###############################################################################
    1616
     
    4343        clock.hfa \
    4444        exception.hfa \
     45        exception.h \
    4546        gmp.hfa \
    4647        math.hfa \
     
    5152        bits/defs.hfa \
    5253        bits/locks.hfa \
     54        bits/collection.hfa \
     55        bits/stack.hfa \
     56        bits/queue.hfa \
     57        bits/sequence.hfa \
    5358        concurrency/iofwd.hfa \
    5459        containers/list.hfa \
     
    7782        bits/debug.cfa \
    7883        exception.c \
    79         exception.h \
    8084        interpose.cfa \
    8185        lsda.h \
     
    195199        -rm -rf ${CFA_INCDIR} ${CFA_LIBDIR}
    196200
     201distclean-local:
     202        find ${builddir} -path '*.Plo' -delete
     203
    197204
    198205# $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
  • libcfa/src/bits/collection.hfa

    r6a45bd78 r3e3f236  
    77
    88inline {
     9        // PUBLIC
     10
    911        void ?{}( Colable & co ) with( co ) {
    1012                next = 0p;
     
    1618        }
    1719
    18         Colable * getNext( Colable & co ) with( co ) {
    19                 return next;
     20        Colable & getNext( Colable & co ) with( co ) {
     21                return *next;
    2022        }
     23
     24        // PRIVATE
    2125
    2226        Colable *& Next( Colable * cp ) {
     
    2428        }
    2529
     30        // wrappers to make Collection have T
    2631        forall( dtype T ) {
    2732                T *& Next( T * n ) {
  • libcfa/src/bits/queue.hfa

    r6a45bd78 r3e3f236  
    11#pragma once
    22
    3 #include "collection.hfa"
     3#include "bits/collection.hfa"
    44
    55forall( dtype T ) {
     
    2828
    2929                T * succ( Queue(T) & q, T * n ) with( q ) {             // pre: *n in *q
    30 #ifdef __CFA_DEBUG__
     30                        #ifdef __CFA_DEBUG__
    3131                        if ( ! listed( n ) ) abort( "(Queue &)%p.succ( %p ) : Node is not on a list.", &q, n );
    32 #endif // __CFA_DEBUG__
     32                        #endif // __CFA_DEBUG__
    3333                        return (Next( n ) == n) ? 0p : Next( n );
    3434                } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *q
    3535
    3636                void addHead( Queue(T) & q, T & n ) with( q ) {
    37 #ifdef __CFA_DEBUG__
     37                        #ifdef __CFA_DEBUG__
    3838                        if ( listed( &n ) ) abort( "(Queue &)%p.addHead( %p ) : Node is already on another list.", &q, &n );
    39 #endif // __CFA_DEBUG__
     39                        #endif // __CFA_DEBUG__
    4040                        if ( last ) {
    4141                                Next( &n ) = &head( q );
     
    4343                        } else {
    4444                                root = last = &n;
    45                                 Next( &n ) = &n;                                                        // last node points to itself
     45                                Next( &n ) = &n;                                                // last node points to itself
    4646                        }
    4747                }
    4848
    4949                void addTail( Queue(T) & q, T & n ) with( q ) {
    50 #ifdef __CFA_DEBUG__
     50                        #ifdef __CFA_DEBUG__
    5151                        if ( listed( &n ) ) abort( "(Queue &)%p.addTail( %p ) : Node is already on another list.", &q, &n );
    52 #endif // __CFA_DEBUG__
     52                        #endif // __CFA_DEBUG__
    5353                        if ( last ) Next( last ) = &n;
    5454                        else root = &n;
    5555                        last = &n;
    56                         Next( &n ) = &n;                                                                // last node points to itself
     56                        Next( &n ) = &n;                                                        // last node points to itself
    5757                }
    5858
     
    7878
    7979                void remove( Queue(T) & q, T & n ) with( q ) {  // O(n)
    80 #ifdef __CFA_DEBUG__
     80                        #ifdef __CFA_DEBUG__
    8181                        if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.remove( %p ) : Node is not on a list.", &q, &n );
    82 #endif // __CFA_DEBUG__
     82                        #endif // __CFA_DEBUG__
    8383                        T * prev = 0p;
    8484                        T * curr = (T *)root;
     
    9696                                        break;
    9797                                }
    98 #ifdef __CFA_DEBUG__
    9998                                // not found => error
    100                                 if (curr == last) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, &n );
    101 #endif // __CFA_DEBUG__
     99                                #ifdef __CFA_DEBUG__
     100                                if ( curr == last ) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, &n );
     101                                #endif // __CFA_DEBUG__
    102102                                prev = curr;
    103103                                curr = Next( curr );
     
    125125                // Node "n" must be in the "from" list.
    126126                void split( Queue(T) & q, Queue(T) & from, T & n ) with( q ) {
    127 #ifdef __CFA_DEBUG__
     127                        #ifdef __CFA_DEBUG__
    128128                        if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.split( %p ) : Node is not on a list.", &q, &n );
    129 #endif // __CFA_DEBUG__
     129                        #endif // __CFA_DEBUG__
    130130                        Queue(T) to;
    131131                        to.root = from.root;                                            // start of "to" list
     
    177177        } // distribution
    178178} // distribution
    179 
    180 // Local Variables: //
    181 // compile-command: "cfa queue.cfa" //
    182 // End: //
  • libcfa/src/bits/sequence.hfa

    r6a45bd78 r3e3f236  
    11#pragma once
    22
    3 #include "collection.hfa"
     3#include "bits/collection.hfa"
    44
    55struct Seqable {
     
    99
    1010inline {
     11        // PUBLIC
     12
    1113        void ?{}( Seqable & sq ) with( sq ) {
    12                 ((Colable &) sq){};
     14                ((Colable &)sq){};
    1315                back = 0p;
    1416        } // post: ! listed()
     
    1820        }
    1921
     22        // PRIVATE
     23
    2024        Seqable *& Back( Seqable * sq ) {
    2125                return sq->back;
    2226        }
     27
     28        // wrappers to make Collection have T
     29        forall( dtype T ) {
     30                T *& Back( T * n ) {
     31                        return (T *)Back( (Seqable *)n );
     32                }
     33        } // distribution
    2334} // distribution
    2435
     
    3445                } // post: empty() & head() == 0 | !empty() & head() in *s
    3546
    36                 T *& Back( T * n ) {
    37                         return (T *)Back( (Seqable *)n );
    38                 }
    39 
    4047                void ?{}( Sequence(T) &, const Sequence(T) & ) = void; // no copy
    4148                Sequence(T) & ?=?( const Sequence(T) & ) = void; // no assignment
    4249
    4350                void ?{}( Sequence(T) & s ) with( s ) {
    44                         ((Collection &) s){};
     51                        ((Collection &)s){};
    4552                }       // post: isEmpty().
    4653
     
    5057                }       // post: empty() & tail() == 0 | !empty() & tail() in *s
    5158
    52                 // Return a pointer to the element after *n, or 0p if there isn't one.
     59                // Return a pointer to the element after *n, or 0p if list empty.
    5360                T * succ( Sequence(T) & s, T * n ) with( s ) {  // pre: *n in *s
    54 #ifdef __CFA_DEBUG__
     61                        #ifdef __CFA_DEBUG__
    5562                        if ( ! listed( n ) ) abort( "(Sequence &)%p.succ( %p ) : Node is not on a list.", &s, n );
    56 #endif // __CFA_DEBUG__
     63                        #endif // __CFA_DEBUG__
    5764                        return Next( n ) == &head( s ) ? 0p : Next( n );
    5865                } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
     
    6067                // Return a pointer to the element before *n, or 0p if there isn't one.
    6168                T * pred( Sequence(T) & s, T * n ) with( s ) {  // pre: *n in *s
    62 #ifdef __CFA_DEBUG__
     69                        #ifdef __CFA_DEBUG__
    6370                        if ( ! listed( n ) ) abort( "(Sequence &)%p.pred( %p ) : Node is not on a list.", &s, n );
    64 #endif // __CFA_DEBUG__
     71                        #endif // __CFA_DEBUG__
    6572                        return n == &head( s ) ? 0p : Back( n );
    6673                }       // post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
     
    6976                // Insert *n into the sequence before *bef, or at the end if bef == 0.
    7077                void insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s
    71 #ifdef __CFA_DEBUG__
     78                        #ifdef __CFA_DEBUG__
    7279                        if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef );
    73 #endif // __CFA_DEBUG__
     80                        #endif // __CFA_DEBUG__
    7481                        if ( &bef == &head( s ) ) {                                     // must change root
    7582                                if ( root ) {
     
    101108                // Insert *n into the sequence after *aft, or at the beginning if aft == 0.
    102109                void insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {   // pre: !n->listed() & *aft in *s
    103 #ifdef __CFA_DEBUG__
     110                        #ifdef __CFA_DEBUG__
    104111                        if ( listed( &n ) ) abort( "(Sequence &)%p.insertAft( %p, %p ) : Node is already on another list.", &s, &aft, &n );
    105 #endif // __CFA_DEBUG__
     112                        #endif // __CFA_DEBUG__
    106113                        if ( ! &aft ) {                                                         // must change root
    107114                                if ( root ) {
     
    130137                // pre: n->listed() & *n in *s
    131138                void remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
    132 #ifdef __CFA_DEBUG__
     139                        #ifdef __CFA_DEBUG__
    133140                        if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n );
    134 #endif // __CFA_DEBUG__
     141                        #endif // __CFA_DEBUG__
    135142                        if ( &n == &head( s ) ) {
    136143                                if ( Next( &head( s ) ) == &head( s ) ) root = 0p;
     
    188195                // Node "n" must be in the "from" list.
    189196                void split( Sequence(T) & s, Sequence(T) & from, T & n ) with( s ) {
    190 #ifdef __CFA_DEBUG__
     197                        #ifdef __CFA_DEBUG__
    191198                        if ( ! listed( &n ) ) abort( "(Sequence &)%p.split( %p ) : Node is not on a list.", &s, &n );
    192 #endif // __CFA_DEBUG__
     199                        #endif // __CFA_DEBUG__
    193200                        Sequence(T) to;
    194201                        to.root = from.root;                                            // start of "to" list
     
    199206                                Back( &head( from ) ) = Back( &head( to ) ); // fix "from" list
    200207                                Next( Back( &head( to ) ) ) = &head( from );
    201                                 Next( &n ) = &head( to );                                       // fix "to" list
     208                                Next( &n ) = &head( to );                               // fix "to" list
    202209                                Back( &head( to ) ) = &n;
    203210                        } // if
     
    214221                // passing the sequence, traversing would require its length. Thus the iterator needs a pointer to the sequence
    215222                // to pass to succ/pred. Both stack and queue just encounter 0p since the lists are not circular.
    216                 Sequence(T) * seq;
     223                Sequence(T) * seq;                                                              // FIX ME: cannot be reference
    217224        };
    218225
     
    224231
    225232                void ?{}( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
    226                         ((ColIter &) si){};
     233                        ((ColIter &)si){};
    227234                        seq = &s;
    228235                        curr = &head( s );
     
    230237
    231238                void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) {
    232                         ((ColIter &) si){};
     239                        ((ColIter &)si){};
    233240                        seq = &s;
    234241                        curr = &start;
     
    255262                inline ColIter;
    256263                // See above for explanation.
    257                 Sequence(T) * seq;
     264                Sequence(T) * seq;                                                              // FIX ME: cannot be reference
    258265        };
    259266
    260267        inline {
    261268                void ?{}( SeqIterRev(T) & si ) with( si ) {     
    262                         ((ColIter &) si){};
     269                        ((ColIter &)si){};
    263270                        seq = 0p;
    264271                } // post: elts = null.
    265272
    266273                void ?{}( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {   
    267                         ((ColIter &) si){};
     274                        ((ColIter &)si){};
    268275                        seq = &s;
    269276                        curr = &tail( s );
     
    271278
    272279                void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) {
    273                         ((ColIter &) si){};
     280                        ((ColIter &)si){};
    274281                        seq = &s;
    275282                        curr = &start;
     
    291298        } // distribution
    292299} // distribution
    293 
    294 // Local Variables: //
    295 // compile-command: "cfa sequence.hfa" //
    296 // End: //
  • libcfa/src/bits/stack.hfa

    r6a45bd78 r3e3f236  
    11#pragma once
    22
    3 #include "collection.hfa"
     3#include "bits/collection.hfa"
    44
    55forall( dtype T ) {
     
    2626
    2727                void addHead( Stack(T) & s, T & n ) with( s ) {
    28 #ifdef __CFA_DEBUG__
     28                        #ifdef __CFA_DEBUG__
    2929                        if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
    30 #endif // __CFA_DEBUG__
     30                        #endif // __CFA_DEBUG__
    3131                        Next( &n ) = &head( s ) ? &head( s ) : &n;
    3232                        root = &n;
     
    4444                        T & t = head( s );
    4545                        if ( root ) {
    46                                 root = ( T *)Next(root);
     46                                root = ( T *)Next( root );
    4747                                if ( &head( s ) == &t ) root = 0p;              // only one element ?
    4848                                Next( &t ) = 0p;
     
    9292        } // distribution
    9393} // distribution
    94 
    95 // Local Variables: //
    96 // compile-command: "make install" //
    97 // End: //
  • libcfa/src/concurrency/coroutine.cfa

    r6a45bd78 r3e3f236  
    2828#include "kernel_private.hfa"
    2929#include "exception.hfa"
     30#include "math.hfa"
    3031
    3132#define __CFA_INVOKE_PRIVATE__
     
    8788
    8889void __stack_prepare( __stack_info_t * this, size_t create_size );
     90void __stack_clean  ( __stack_info_t * this );
    8991
    9092//-----------------------------------------------------------------------------
     
    107109        bool userStack = ((intptr_t)this.storage & 0x1) != 0;
    108110        if ( ! userStack && this.storage ) {
    109                 __attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage;
    110                 *istorage &= (intptr_t)-1;
    111 
    112                 void * storage = this.storage->limit;
    113                 __cfaabi_dbg_debug_do(
    114                         storage = (char*)(storage) - __page_size;
    115                         if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) {
    116                                 abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
    117                         }
    118                 );
    119                 __cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
    120                 free( storage );
     111                __stack_clean( &this );
     112                // __attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage;
     113                // *istorage &= (intptr_t)-1;
     114
     115                // void * storage = this.storage->limit;
     116                // __cfaabi_dbg_debug_do(
     117                //      storage = (char*)(storage) - __page_size;
     118                //      if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) {
     119                //              abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
     120                //      }
     121                // );
     122                // __cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
     123                // free( storage );
    121124        }
    122125}
     
    167170        assert(__page_size != 0l);
    168171        size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
     172        size = ceiling(size, __page_size);
    169173
    170174        // If we are running debug, we also need to allocate a guardpage to catch stack overflows.
    171175        void * storage;
    172         __cfaabi_dbg_debug_do(
    173                 storage = memalign( __page_size, size + __page_size );
    174         );
    175         __cfaabi_dbg_no_debug_do(
    176                 storage = (void*)malloc(size);
    177         );
    178 
    179         __cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size);
    180         __cfaabi_dbg_debug_do(
    181                 if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
    182                         abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
    183                 }
    184                 storage = (void *)(((intptr_t)storage) + __page_size);
    185         );
     176        // __cfaabi_dbg_debug_do(
     177        //      storage = memalign( __page_size, size + __page_size );
     178        // );
     179        // __cfaabi_dbg_no_debug_do(
     180        //      storage = (void*)malloc(size);
     181        // );
     182
     183        // __cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size);
     184        // __cfaabi_dbg_debug_do(
     185        //      if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
     186        //              abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     187        //      }
     188        //      storage = (void *)(((intptr_t)storage) + __page_size);
     189        // );
     190        storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
     191        if(storage == ((void*)-1)) {
     192                abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
     193        }
     194        if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
     195                abort( "coroutine stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
     196        } // if
     197        storage = (void *)(((intptr_t)storage) + __page_size);
    186198
    187199        verify( ((intptr_t)storage & (libAlign() - 1)) == 0ul );
    188200        return [storage, size];
     201}
     202
     203void __stack_clean  ( __stack_info_t * this ) {
     204        size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);
     205        void * storage = this->storage->limit;
     206
     207        storage = (void *)(((intptr_t)storage) - __page_size);
     208        if(munmap(storage, size + __page_size) == -1) {
     209                abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
     210        }
    189211}
    190212
     
    210232        assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %zd bytes for a stack.", size, MinStackSize );
    211233
    212         this->storage = (__stack_t *)((intptr_t)storage + size);
     234        this->storage = (__stack_t *)((intptr_t)storage + size - sizeof(__stack_t));
    213235        this->storage->limit = storage;
    214         this->storage->base  = (void*)((intptr_t)storage + size);
     236        this->storage->base  = (void*)((intptr_t)storage + size - sizeof(__stack_t));
    215237        this->storage->exception_context.top_resume = 0p;
    216238        this->storage->exception_context.current_exception = 0p;
  • libcfa/src/concurrency/coroutine.hfa

    r6a45bd78 r3e3f236  
    102102}
    103103
    104 extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
     104extern void __stack_prepare( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
     105extern void __stack_clean  ( __stack_info_t * this );
     106
    105107
    106108// Suspend implementation inlined for performance
  • libcfa/src/concurrency/io/setup.cfa

    r6a45bd78 r3e3f236  
    132132                // Wait for the io poller thread to finish
    133133
    134                 pthread_join( iopoll.thrd, 0p );
    135                 free( iopoll.stack );
     134                __destroy_pthread( iopoll.thrd, iopoll.stack, 0p );
    136135
    137136                int ret = close(iopoll.epollfd);
  • libcfa/src/concurrency/kernel/startup.cfa

    r6a45bd78 r3e3f236  
    2929#include "kernel_private.hfa"
    3030#include "startup.hfa"          // STARTUP_PRIORITY_XXX
     31#include "math.hfa"
    3132
    3233//-----------------------------------------------------------------------------
     
    539540}
    540541
     542extern size_t __page_size;
    541543void ^?{}(processor & this) with( this ){
    542544        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
     
    550552        }
    551553
    552         int err = pthread_join( kernel_thread, 0p );
    553         if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err));
    554 
    555         free( this.stack );
     554        __destroy_pthread( kernel_thread, this.stack, 0p );
    556555
    557556        disable_interrupts();
     
    678677
    679678        void * stack;
    680         __cfaabi_dbg_debug_do(
    681                 stack = memalign( __page_size, stacksize + __page_size );
    682                 // pthread has no mechanism to create the guard page in user supplied stack.
    683                 if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
    684                         abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
    685                 } // if
    686         );
    687         __cfaabi_dbg_no_debug_do(
    688                 stack = malloc( stacksize );
    689         );
     679        #warning due to the thunk problem, stack creation uses mmap, revert to malloc once this goes away
     680        // __cfaabi_dbg_debug_do(
     681        //      stack = memalign( __page_size, stacksize + __page_size );
     682        //      // pthread has no mechanism to create the guard page in user supplied stack.
     683        //      if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
     684        //              abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
     685        //      } // if
     686        // );
     687        // __cfaabi_dbg_no_debug_do(
     688        //      stack = malloc( stacksize );
     689        // );
     690        stacksize = ceiling( stacksize, __page_size ) + __page_size;
     691        stack = mmap(0p, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
     692        if(stack == ((void*)-1)) {
     693                abort( "pthread stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
     694        }
     695        if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
     696                abort( "pthread stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
     697        } // if
    690698
    691699        check( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
     
    694702        return stack;
    695703}
     704
     705void __destroy_pthread( pthread_t pthread, void * stack, void ** retval ) {
     706        int err = pthread_join( pthread, retval );
     707        if( err != 0 ) abort("KERNEL ERROR: joining pthread %p caused error %s\n", (void*)pthread, strerror(err));
     708
     709        pthread_attr_t attr;
     710
     711        check( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute
     712
     713        size_t stacksize;
     714        // default stack size, normally defined by shell limit
     715        check( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );
     716        assert( stacksize >= PTHREAD_STACK_MIN );
     717        stacksize += __page_size;
     718
     719        if(munmap(stack, stacksize) == -1) {
     720                abort( "pthread stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
     721        }
     722}
     723
    696724
    697725#if defined(__CFA_WITH_VERIFY__)
  • libcfa/src/concurrency/kernel_private.hfa

    r6a45bd78 r3e3f236  
    4949
    5050void * __create_pthread( pthread_t *, void * (*)(void *), void * );
     51void __destroy_pthread( pthread_t pthread, void * stack, void ** retval );
    5152
    5253
  • libcfa/src/concurrency/preemption.cfa

    r6a45bd78 r3e3f236  
    354354}
    355355
     356//-----------------------------------------------------------------------------
     357// Kernel Signal Debug
     358void __cfaabi_check_preemption() {
     359        bool ready = __preemption_enabled();
     360        if(!ready) { abort("Preemption should be ready"); }
     361
     362        __cfaasm_label(debug, before);
     363
     364                sigset_t oldset;
     365                int ret;
     366                ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
     367                if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
     368
     369                ret = sigismember(&oldset, SIGUSR1);
     370                if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
     371                if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
     372
     373                ret = sigismember(&oldset, SIGALRM);
     374                if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
     375                if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
     376
     377                ret = sigismember(&oldset, SIGTERM);
     378                if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
     379                if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
     380
     381        __cfaasm_label(debug, after);
     382}
     383
     384#ifdef __CFA_WITH_VERIFY__
     385bool __cfaabi_dbg_in_kernel() {
     386        return !__preemption_enabled();
     387}
     388#endif
     389
    356390#undef __cfaasm_label
     391
     392//-----------------------------------------------------------------------------
     393// Signal handling
    357394
    358395// sigprocmask wrapper : unblock a single signal
     
    405442                #define RELOC_SUFFIX ""
    406443        #endif
    407         #define __cfaasm_label( label ) static struct asm_region label = \
     444        #define __cfaasm_label( label ) struct asm_region label = \
    408445                ({ \
    409446                        struct asm_region region; \
     
    424461                #define RELOC_SUFFIX ""
    425462        #endif
    426         #define __cfaasm_label( label ) static struct asm_region label = \
     463        #define __cfaasm_label( label ) struct asm_region label = \
    427464                ({ \
    428465                        struct asm_region region; \
     
    437474        #ifdef __PIC__
    438475                // Note that this works only for gcc
    439                 #define __cfaasm_label( label ) static struct asm_region label = \
     476                #define __cfaasm_label( label ) struct asm_region label = \
    440477                ({ \
    441478                        struct asm_region region; \
     
    452489                #error this is not the right thing to do
    453490                /*
    454                 #define __cfaasm_label( label ) static struct asm_region label = \
     491                #define __cfaasm_label( label ) struct asm_region label = \
    455492                ({ \
    456493                        struct asm_region region; \
     
    479516        __cfaasm_label( check  );
    480517        __cfaasm_label( dsable );
     518        __cfaasm_label( debug  );
    481519
    482520        // Check if preemption is safe
     
    485523        if( __cfaasm_in( ip, check  ) ) { ready = false; goto EXIT; };
    486524        if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; };
     525        if( __cfaasm_in( ip, debug  ) ) { ready = false; goto EXIT; };
    487526        if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
    488527        if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
     
    536575        // Wait for the preemption thread to finish
    537576
    538         pthread_join( alarm_thread, 0p );
    539         free( alarm_stack );
     577        __destroy_pthread( alarm_thread, alarm_stack, 0p );
    540578
    541579        // Preemption is now fully stopped
     
    697735}
    698736
    699 //=============================================================================================
    700 // Kernel Signal Debug
    701 //=============================================================================================
    702 
    703 void __cfaabi_check_preemption() {
    704         bool ready = __preemption_enabled();
    705         if(!ready) { abort("Preemption should be ready"); }
    706 
    707         sigset_t oldset;
    708         int ret;
    709         ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
    710         if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    711 
    712         ret = sigismember(&oldset, SIGUSR1);
    713         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    714         if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
    715 
    716         ret = sigismember(&oldset, SIGALRM);
    717         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    718         if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
    719 
    720         ret = sigismember(&oldset, SIGTERM);
    721         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    722         if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
    723 }
    724 
    725 #ifdef __CFA_WITH_VERIFY__
    726 bool __cfaabi_dbg_in_kernel() {
    727         return !__preemption_enabled();
    728 }
    729 #endif
    730 
    731737// Local Variables: //
    732738// mode: c //
  • libcfa/src/stdlib.hfa

    r6a45bd78 r3e3f236  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 12 20:58:48 2020
    13 // Update Count     : 520
     12// Last Modified On : Tue Dec  8 18:27:22 2020
     13// Update Count     : 524
    1414//
    1515
     
    268268static inline forall( dtype T | { void ^?{}( T & ); } )
    269269void delete( T * ptr ) {
    270         if ( ptr ) {                                                                            // ignore null
     270        // special case for 0-sized object => always call destructor
     271        if ( ptr || sizeof(ptr) == 0 ) {                                        // ignore null but not 0-sized objects
    271272                ^(*ptr){};                                                                              // run destructor
    272                 free( ptr );
    273273        } // if
     274        free( ptr );
    274275} // delete
    275276
Note: See TracChangeset for help on using the changeset viewer.