Changeset c76bd34 for libcfa/src


Ignore:
Timestamp:
Oct 7, 2020, 4:31:43 PM (5 years ago)
Author:
Colby Alexander Parsons <caparsons@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
848439f
Parents:
ae2c27a (diff), 597c5d18 (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 into master

Location:
libcfa/src
Files:
3 added
30 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    rae2c27a rc76bd34  
    6262        iterator.hfa \
    6363        limits.hfa \
     64        memory.hfa \
    6465        parseargs.hfa \
    6566        rational.hfa \
     
    8788inst_thread_headers_nosrc = \
    8889        bits/random.hfa \
     90        concurrency/clib/cfathread.h \
    8991        concurrency/invoke.h \
    9092        concurrency/kernel/fwd.hfa
     
    102104        concurrency/alarm.cfa \
    103105        concurrency/alarm.hfa \
     106        concurrency/clib/cfathread.cfa \
    104107        concurrency/CtxSwitch-@ARCHITECTURE@.S \
    105108        concurrency/invoke.c \
     
    107110        concurrency/io/setup.cfa \
    108111        concurrency/io/types.hfa \
    109         concurrency/iocall.cfa \
     112        concurrency/io/call.cfa \
    110113        concurrency/iofwd.hfa \
    111114        concurrency/kernel_private.hfa \
  • libcfa/src/bits/locks.hfa

    rae2c27a rc76bd34  
    164164
    165165        struct $thread;
    166         extern void park( __cfaabi_dbg_ctx_param );
    167         extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 );
     166        extern void park( void );
     167        extern void unpark( struct $thread * this );
    168168        static inline struct $thread * active_thread ();
    169169
     
    191191                                        /* paranoid */ verify( expected == 0p );
    192192                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    193                                                 park( __cfaabi_dbg_ctx );
     193                                                park();
    194194                                                return true;
    195195                                        }
     
    210210                                else {
    211211                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    212                                                 unpark( expected __cfaabi_dbg_ctx2 );
     212                                                unpark( expected );
    213213                                                return true;
    214214                                        }
     
    244244                                /* paranoid */ verify( expected == 0p );
    245245                                if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    246                                         park( __cfaabi_dbg_ctx );
     246                                        park();
    247247                                        /* paranoid */ verify( this.ptr == 1p );
    248248                                        return true;
     
    256256                        struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    257257                        if( got == 0p ) return false;
    258                         unpark( got __cfaabi_dbg_ctx2 );
     258                        unpark( got );
    259259                        return true;
    260260                }
     
    357357                                struct oneshot * expected = this.ptr;
    358358                                // was this abandoned?
    359                                 if( expected == 3p ) { free( &this ); return false; }
     359                                #if defined(__GNUC__) && __GNUC__ >= 7
     360                                        #pragma GCC diagnostic push
     361                                        #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
     362                                #endif
     363                                        if( expected == 3p ) { free( &this ); return false; }
     364                                #if defined(__GNUC__) && __GNUC__ >= 7
     365                                        #pragma GCC diagnostic pop
     366                                #endif
    360367
    361368                                /* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen
  • libcfa/src/concurrency/CtxSwitch-i386.S

    rae2c27a rc76bd34  
    1010// Created On       : Tue Dec 6 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Aug 16 08:46:22 2020
    13 // Update Count     : 4
     12// Last Modified On : Sun Sep  6 18:23:37 2020
     13// Update Count     : 5
    1414//
    1515
     
    3535
    3636        // Copy the "from" context argument from the stack to register eax
    37         // Return address is at 0(%esp), with parameters following
     37        // Return address is at 0(%esp), with parameters following.
    3838
    3939        movl 4(%esp),%eax
     
    5050        movl %ebp,FP_OFFSET(%eax)
    5151
    52         // Copy the "to" context argument from the stack to register eax
    53         // Having pushed three words (= 12 bytes) on the stack, the
    54         // argument is now at 8 + 12 = 20(%esp)
     52        // Copy the "to" context argument from the stack to register eax. Having
     53        // pushed 3 words (= 12 bytes) on the stack, the argument is now at
     54        // 8 + 12 = 20(%esp).
    5555
    5656        movl 20(%esp),%eax
  • libcfa/src/concurrency/alarm.cfa

    rae2c27a rc76bd34  
    130130
    131131        register_self( &node );
    132         park( __cfaabi_dbg_ctx );
     132        park();
    133133
    134134        /* paranoid */ verify( !node.set );
  • libcfa/src/concurrency/coroutine.cfa

    rae2c27a rc76bd34  
    4747
    4848//-----------------------------------------------------------------------------
     49FORALL_DATA_INSTANCE(CoroutineCancelled,
     50                (dtype coroutine_t | sized(coroutine_t)), (coroutine_t))
     51
     52struct __cfaehm_node {
     53        struct _Unwind_Exception unwind_exception;
     54        struct __cfaehm_node * next;
     55        int handler_index;
     56};
     57
     58forall(dtype T)
     59void mark_exception(CoroutineCancelled(T) *) {}
     60
     61forall(dtype T | sized(T))
     62void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
     63        dst->the_coroutine = src->the_coroutine;
     64        dst->the_exception = src->the_exception;
     65}
     66
     67forall(dtype T)
     68const char * msg(CoroutineCancelled(T) *) {
     69        return "CoroutineCancelled(...)";
     70}
     71
     72// This code should not be inlined. It is the error path on resume.
     73forall(dtype T | is_coroutine(T))
     74void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) {
     75        verify( desc->cancellation );
     76        desc->state = Cancelled;
     77        exception_t * except = (exception_t *)(1 + (__cfaehm_node *)desc->cancellation);
     78
     79        CoroutineCancelled(T) except;
     80        except.the_coroutine = &cor;
     81        except.the_exception = except;
     82        throwResume except;
     83
     84        except->virtual_table->free( except );
     85        free( desc->cancellation );
     86        desc->cancellation = 0p;
     87}
     88
     89//-----------------------------------------------------------------------------
    4990// Global state variables
    5091
     
    180221        this->storage->limit = storage;
    181222        this->storage->base  = (void*)((intptr_t)storage + size);
     223        this->storage->exception_context.top_resume = 0p;
     224        this->storage->exception_context.current_exception = 0p;
    182225        __attribute__((may_alias)) intptr_t * istorage = (intptr_t*)&this->storage;
    183226        *istorage |= userStack ? 0x1 : 0x0;
  • libcfa/src/concurrency/coroutine.hfa

    rae2c27a rc76bd34  
    1818#include <assert.h>
    1919#include "invoke.h"
     20#include "../exception.hfa"
     21
     22//-----------------------------------------------------------------------------
     23// Exception thrown from resume when a coroutine stack is cancelled.
     24// Should not have to be be sized (see trac #196).
     25FORALL_DATA_EXCEPTION(CoroutineCancelled,
     26                (dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) (
     27        coroutine_t * the_coroutine;
     28        exception_t * the_exception;
     29);
     30
     31forall(dtype T)
     32void mark_exception(CoroutineCancelled(T) *);
     33
     34forall(dtype T | sized(T))
     35void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src);
     36
     37forall(dtype T)
     38const char * msg(CoroutineCancelled(T) *);
    2039
    2140//-----------------------------------------------------------------------------
     
    2342// Anything that implements this trait can be resumed.
    2443// Anything that is resumed is a coroutine.
    25 trait is_coroutine(dtype T) {
    26       void main(T & this);
    27       $coroutine * get_coroutine(T & this);
     44trait is_coroutine(dtype T | sized(T)
     45                | is_resumption_exception(CoroutineCancelled(T))
     46                | VTABLE_ASSERTION(CoroutineCancelled, (T))) {
     47        void main(T & this);
     48        $coroutine * get_coroutine(T & this);
    2849};
    2950
     
    112133        }
    113134}
     135
     136forall(dtype T | is_coroutine(T))
     137void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc );
    114138
    115139// Resume implementation inlined for performance
     
    145169        // always done for performance testing
    146170        $ctx_switch( src, dst );
     171        if ( unlikely(dst->cancellation) ) {
     172                __cfaehm_cancelled_coroutine( cor, dst );
     173        }
    147174
    148175        return cor;
  • libcfa/src/concurrency/exception.cfa

    rae2c27a rc76bd34  
    5757
    5858STOP_AT_END_FUNCTION(coroutine_cancelstop,
    59         // TODO: Instead pass information to the last resumer.
     59        struct $coroutine * src = ($coroutine *)stop_param;
     60        struct $coroutine * dst = src->last;
     61
     62        $ctx_switch( src, dst );
    6063        abort();
    6164)
  • libcfa/src/concurrency/exception.hfa

    rae2c27a rc76bd34  
    1818#include "bits/defs.hfa"
    1919#include "invoke.h"
    20 struct _Unwind_Exception;
    21 
    22 // It must also be usable as a C header file.
    2320
    2421#ifdef __cforall
    2522extern "C" {
     23
     24#define HIDE_EXPORTS
    2625#endif
     26#include "unwind.h"
    2727
    2828struct exception_context_t * this_exception_context(void) OPTIONAL_THREAD;
     
    3232
    3333#ifdef __cforall
     34#undef HIDE_EXPORTS
    3435}
    3536#endif
  • libcfa/src/concurrency/invoke.h

    rae2c27a rc76bd34  
    6868        };
    6969
    70         enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active };
     70        enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active, Cancelled };
    7171
    7272        struct $coroutine {
     
    9393
    9494        };
     95        // Wrapper for gdb
     96        struct cfathread_coroutine_t { struct $coroutine debug; };
    9597
    9698        static inline struct __stack_t * __get_stack( struct $coroutine * cor ) {
     
    129131                struct __condition_node_t * dtor_node;
    130132        };
     133        // Wrapper for gdb
     134        struct cfathread_monitor_t { struct $monitor debug; };
    131135
    132136        struct __monitor_group_t {
     
    186190                } node;
    187191
    188                 #ifdef __CFA_DEBUG__
    189                         // previous function to park/unpark the thread
    190                         const char * park_caller;
    191                         int park_result;
    192                         enum __Coroutine_State park_state;
    193                         bool park_stale;
    194                         const char * unpark_caller;
    195                         int unpark_result;
    196                         enum __Coroutine_State unpark_state;
    197                         bool unpark_stale;
     192                #if defined( __CFA_WITH_VERIFY__ )
     193                        unsigned long long canary;
    198194                #endif
    199195        };
     196        // Wrapper for gdb
     197        struct cfathread_thread_t { struct $thread debug; };
    200198
    201199        #ifdef __CFA_DEBUG__
  • libcfa/src/concurrency/io.cfa

    rae2c27a rc76bd34  
    6969                if( block ) {
    7070                        enable_interrupts( __cfaabi_dbg_ctx );
    71                         park( __cfaabi_dbg_ctx );
     71                        park();
    7272                        disable_interrupts();
    7373                }
     
    9797
    9898                if(nextt) {
    99                         unpark( nextt __cfaabi_dbg_ctx2 );
     99                        unpark( nextt );
    100100                        enable_interrupts( __cfaabi_dbg_ctx );
    101101                        return true;
     
    159159
    160160        static inline void process(struct io_uring_cqe & cqe ) {
    161                 struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data;
    162                 __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", data, cqe.res, data->thrd );
    163 
    164                 data->result = cqe.res;
    165                 post( data->sem );
     161                struct io_future_t * future = (struct io_future_t *)(uintptr_t)cqe.user_data;
     162                __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", future, cqe.res, data->thrd );
     163
     164                fulfil( *future, cqe.res );
    166165        }
    167166
  • libcfa/src/concurrency/io/setup.cfa

    rae2c27a rc76bd34  
    147147        static void * iopoll_loop( __attribute__((unused)) void * args ) {
    148148                __processor_id_t id;
     149                id.full_proc = false;
    149150                id.id = doregister(&id);
    150151                __cfaabi_dbg_print_safe( "Kernel : IO poller thread starting\n" );
     
    246247                                        thrd.link.next = 0p;
    247248                                        thrd.link.prev = 0p;
    248                                         __cfaabi_dbg_debug_do( thrd.unpark_stale = true );
    249249
    250250                                        // Fixup the thread state
     
    266266
    267267                                // unpark the fast io_poller
    268                                 unpark( &thrd __cfaabi_dbg_ctx2 );
     268                                unpark( &thrd );
    269269                        }
    270270                        else {
     
    275275                        }
    276276                } else {
    277                         unpark( &thrd __cfaabi_dbg_ctx2 );
     277                        unpark( &thrd );
    278278                }
    279279
  • libcfa/src/concurrency/io/types.hfa

    rae2c27a rc76bd34  
    1616#pragma once
    1717
     18extern "C" {
     19        #include <linux/types.h>
     20}
     21
     22#include "bits/locks.hfa"
     23
    1824#if defined(CFA_HAVE_LINUX_IO_URING_H)
    19         extern "C" {
    20                 #include <linux/types.h>
    21         }
    22 
    23       #include "bits/locks.hfa"
    24 
    2525        #define LEADER_LOCK
    2626        struct __leaderlock_t {
     
    101101        };
    102102
    103 
    104         //-----------------------------------------------------------------------
    105         // IO user data
    106         struct __io_user_data_t {
    107                 __s32 result;
    108                 oneshot sem;
    109         };
    110 
    111103        //-----------------------------------------------------------------------
    112104        // Misc
     
    143135        void __ioctx_prepare_block($io_ctx_thread & ctx, struct epoll_event & ev);
    144136#endif
     137
     138//-----------------------------------------------------------------------
     139// IO user data
     140struct io_future_t {
     141        future_t self;
     142        __s32 result;
     143};
     144
     145static inline {
     146        bool fulfil( io_future_t & this, __s32 result ) {
     147                this.result = result;
     148                return fulfil(this.self);
     149        }
     150
     151        // Wait for the future to be fulfilled
     152        bool wait( io_future_t & this ) {
     153                return wait(this.self);
     154        }
     155}
  • libcfa/src/concurrency/iofwd.hfa

    rae2c27a rc76bd34  
    4040
    4141struct cluster;
     42struct io_future_t;
    4243struct io_context;
    4344struct io_cancellation;
     
    4849struct statx;
    4950
    50 extern ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    51 extern ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    52 extern int cfa_fsync(int fd, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    53 extern int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    54 extern ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    55 extern ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    56 extern ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    57 extern ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    58 extern int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    59 extern int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    60 extern int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    61 extern int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    62 extern int cfa_madvise(void *addr, size_t length, int advice, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    63 extern int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    64 extern int cfa_close(int fd, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    65 extern int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    66 extern ssize_t cfa_read(int fd, void *buf, size_t count, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    67 extern ssize_t cfa_write(int fd, void *buf, size_t count, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    68 extern ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
    69 extern ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, int submit_flags = 0, Duration timeout = -1`s, io_cancellation * cancellation = 0p, io_context * context = 0p);
     51//----------
     52// synchronous calls
     53#if defined(CFA_HAVE_PREADV2)
     54        extern ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     55#endif
     56#if defined(CFA_HAVE_PWRITEV2)
     57        extern ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     58#endif
     59extern int cfa_fsync(int fd, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     60extern int cfa_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     61extern int cfa_sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     62extern  ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     63extern ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     64extern ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     65extern ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     66extern int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     67extern int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     68extern int cfa_fallocate(int fd, int mode, off_t offset, off_t len, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     69extern int cfa_posix_fadvise(int fd, off_t offset, off_t len, int advice, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     70extern int cfa_madvise(void *addr, size_t length, int advice, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     71extern int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     72#if defined(CFA_HAVE_OPENAT2)
     73        extern int cfa_openat2(int dirfd, const char *pathname, struct open_how * how, size_t size, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     74#endif
     75extern int cfa_close(int fd, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     76#if defined(CFA_HAVE_STATX)
     77        extern int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     78#endif
     79extern ssize_t cfa_read(int fd, void * buf, size_t count, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     80extern ssize_t cfa_write(int fd, void * buf, size_t count, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     81extern ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     82extern ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
     83
     84//----------
     85// asynchronous calls
     86#if defined(CFA_HAVE_PREADV2)
     87        extern void async_preadv2(io_future_t & future, int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     88#endif
     89#if defined(CFA_HAVE_PWRITEV2)
     90        extern void async_pwritev2(io_future_t & future, int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     91#endif
     92extern void async_fsync(io_future_t & future, int fd, int submit_flags, io_cancellation * cancellation, io_context * context);
     93extern void async_epoll_ctl(io_future_t & future, int epfd, int op, int fd, struct epoll_event *event, int submit_flags, io_cancellation * cancellation, io_context * context);
     94extern void async_sync_file_range(io_future_t & future, int fd, off64_t offset, off64_t nbytes, unsigned int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     95extern void async_sendmsg(io_future_t & future, int sockfd, const struct msghdr *msg, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     96extern void async_recvmsg(io_future_t & future, int sockfd, struct msghdr *msg, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     97extern void async_send(io_future_t & future, int sockfd, const void *buf, size_t len, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     98extern void async_recv(io_future_t & future, int sockfd, void *buf, size_t len, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     99extern void async_accept4(io_future_t & future, int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     100extern void async_connect(io_future_t & future, int sockfd, const struct sockaddr *addr, socklen_t addrlen, int submit_flags, io_cancellation * cancellation, io_context * context);
     101extern void async_fallocate(io_future_t & future, int fd, int mode, off_t offset, off_t len, int submit_flags, io_cancellation * cancellation, io_context * context);
     102extern void async_posix_fadvise(io_future_t & future, int fd, off_t offset, off_t len, int advice, int submit_flags, io_cancellation * cancellation, io_context * context);
     103extern void async_madvise(io_future_t & future, void *addr, size_t length, int advice, int submit_flags, io_cancellation * cancellation, io_context * context);
     104extern void async_openat(io_future_t & future, int dirfd, const char *pathname, int flags, mode_t mode, int submit_flags, io_cancellation * cancellation, io_context * context);
     105#if defined(CFA_HAVE_OPENAT2)
     106        extern void async_openat2(io_future_t & future, int dirfd, const char *pathname, struct open_how * how, size_t size, int submit_flags, io_cancellation * cancellation, io_context * context);
     107#endif
     108extern void async_close(io_future_t & future, int fd, int submit_flags, io_cancellation * cancellation, io_context * context);
     109#if defined(CFA_HAVE_STATX)
     110        extern void async_statx(io_future_t & future, int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, int submit_flags, io_cancellation * cancellation, io_context * context);
     111#endif
     112void async_read(io_future_t & future, int fd, void * buf, size_t count, int submit_flags, io_cancellation * cancellation, io_context * context);
     113extern void async_write(io_future_t & future, int fd, void * buf, size_t count, int submit_flags, io_cancellation * cancellation, io_context * context);
     114extern void async_splice(io_future_t & future, int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     115extern void async_tee(io_future_t & future, int fd_in, int fd_out, size_t len, unsigned int flags, int submit_flags, io_cancellation * cancellation, io_context * context);
     116
    70117
    71118//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/kernel.cfa

    rae2c27a rc76bd34  
    237237        $coroutine * proc_cor = get_coroutine(this->runner);
    238238
    239         // Update global state
    240         kernelTLS.this_thread = thrd_dst;
    241 
    242239        // set state of processor coroutine to inactive
    243240        verify(proc_cor->state == Active);
     
    249246                thrd_dst->state = Active;
    250247
    251                 __cfaabi_dbg_debug_do(
    252                         thrd_dst->park_stale   = true;
    253                         thrd_dst->unpark_stale = true;
    254                 )
     248                // Update global state
     249                kernelTLS.this_thread = thrd_dst;
    255250
    256251                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    257252                /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
     253                /* paranoid */ verify( thrd_dst->context.SP );
    258254                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    259255                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
     256                /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );
     257
     258
    260259
    261260                // set context switch to the thread that the processor is executing
    262                 verify( thrd_dst->context.SP );
    263261                __cfactx_switch( &proc_cor->context, &thrd_dst->context );
    264262                // when __cfactx_switch returns we are back in the processor coroutine
    265263
     264                /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );
    266265                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
    267266                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
     267                /* paranoid */ verify( thrd_dst->context.SP );
    268268                /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    269269                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    270270
     271                // Reset global state
     272                kernelTLS.this_thread = 0p;
    271273
    272274                // We just finished running a thread, there are a few things that could have happened.
     
    286288                        // The thread has halted, it should never be scheduled/run again
    287289                        // We may need to wake someone up here since
    288                         unpark( this->destroyer __cfaabi_dbg_ctx2 );
     290                        unpark( this->destroyer );
    289291                        this->destroyer = 0p;
    290292                        break RUNNING;
     
    296298                // set state of processor coroutine to active and the thread to inactive
    297299                int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST);
    298                 __cfaabi_dbg_debug_do( thrd_dst->park_result = old_ticket; )
    299300                switch(old_ticket) {
    300301                        case 1:
     
    313314        // Just before returning to the processor, set the processor coroutine to active
    314315        proc_cor->state = Active;
    315         kernelTLS.this_thread = 0p;
    316316
    317317        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     
    334334                        __x87_store;
    335335                #endif
    336                 verify( proc_cor->context.SP );
     336                /* paranoid */ verify( proc_cor->context.SP );
     337                /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary );
    337338                __cfactx_switch( &thrd_src->context, &proc_cor->context );
     339                /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary );
    338340                #if defined( __i386 ) || defined( __x86_64 )
    339341                        __x87_load;
     
    367369        /* paranoid */ #endif
    368370        /* paranoid */ verifyf( thrd->link.next == 0p, "Expected null got %p", thrd->link.next );
     371        /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd->canary );
     372
    369373
    370374        if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
     
    403407
    404408// KERNEL ONLY unpark with out disabling interrupts
    405 void __unpark(  struct __processor_id_t * id, $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    406         // record activity
    407         __cfaabi_dbg_record_thrd( *thrd, false, caller );
    408 
     409void __unpark(  struct __processor_id_t * id, $thread * thrd ) {
    409410        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    410         __cfaabi_dbg_debug_do( thrd->unpark_result = old_ticket; thrd->unpark_state = thrd->state; )
    411411        switch(old_ticket) {
    412412                case 1:
     
    426426}
    427427
    428 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
     428void unpark( $thread * thrd ) {
    429429        if( !thrd ) return;
    430430
    431431        disable_interrupts();
    432         __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd __cfaabi_dbg_ctx_fwd2 );
     432        __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd );
    433433        enable_interrupts( __cfaabi_dbg_ctx );
    434434}
    435435
    436 void park( __cfaabi_dbg_ctx_param ) {
     436void park( void ) {
    437437        /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    438438        disable_interrupts();
    439439        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    440440        /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
    441 
    442         // record activity
    443         __cfaabi_dbg_record_thrd( *kernelTLS.this_thread, true, caller );
    444441
    445442        returnToKernel();
     
    521518        disable_interrupts();
    522519                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    523                 bool ret = post( this->idle );
     520                post( this->idle );
    524521        enable_interrupts( __cfaabi_dbg_ctx );
    525522}
     
    649646                // atomically release spin lock and block
    650647                unlock( lock );
    651                 park( __cfaabi_dbg_ctx );
     648                park();
    652649                return true;
    653650        }
     
    670667
    671668        // make new owner
    672         unpark( thrd __cfaabi_dbg_ctx2 );
     669        unpark( thrd );
    673670
    674671        return thrd != 0p;
     
    681678        count += diff;
    682679        for(release) {
    683                 unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 );
     680                unpark( pop_head( waiting ) );
    684681        }
    685682
     
    697694                        this.prev_thrd = kernelTLS.this_thread;
    698695                }
    699 
    700                 void __cfaabi_dbg_record_thrd($thread & this, bool park, const char prev_name[]) {
    701                         if(park) {
    702                                 this.park_caller   = prev_name;
    703                                 this.park_stale    = false;
    704                         }
    705                         else {
    706                                 this.unpark_caller = prev_name;
    707                                 this.unpark_stale  = false;
    708                         }
    709                 }
    710696        }
    711697)
  • libcfa/src/concurrency/kernel.hfa

    rae2c27a rc76bd34  
    2323
    2424extern "C" {
    25 #include <bits/pthreadtypes.h>
     25        #include <bits/pthreadtypes.h>
     26        #include <linux/types.h>
    2627}
    2728
     
    4748// Processor id, required for scheduling threads
    4849struct __processor_id_t {
    49         unsigned id;
     50        unsigned id:24;
     51        bool full_proc:1;
    5052
    5153        #if !defined(__CFA_NO_STATISTICS__)
     
    157159
    158160struct io_cancellation {
    159         uint32_t target;
     161        __u64 target;
    160162};
    161163
  • libcfa/src/concurrency/kernel/fwd.hfa

    rae2c27a rc76bd34  
    118118
    119119        extern "Cforall" {
    120                 extern void park( __cfaabi_dbg_ctx_param );
    121                 extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 );
     120                extern void park( void );
     121                extern void unpark( struct $thread * this );
    122122                static inline struct $thread * active_thread () { return TL_GET( this_thread ); }
    123123
  • libcfa/src/concurrency/kernel/startup.cfa

    rae2c27a rc76bd34  
    451451        link.next = 0p;
    452452        link.prev = 0p;
     453        #if defined( __CFA_WITH_VERIFY__ )
     454                canary = 0x0D15EA5E0D15EA5E;
     455        #endif
    453456
    454457        node.next = 0p;
     
    470473        this.name = name;
    471474        this.cltr = &_cltr;
    472         id = -1u;
     475        full_proc = true;
    473476        destroyer = 0p;
    474477        do_terminate = false;
  • libcfa/src/concurrency/kernel_private.hfa

    rae2c27a rc76bd34  
    6464
    6565// KERNEL ONLY unpark with out disabling interrupts
    66 void __unpark( struct __processor_id_t *, $thread * thrd __cfaabi_dbg_ctx_param2 );
     66void __unpark( struct __processor_id_t *, $thread * thrd );
    6767
    6868static inline bool __post(single_sem & this, struct __processor_id_t * id) {
     
    7777                else {
    7878                        if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    79                                 __unpark( id, expected __cfaabi_dbg_ctx2 );
     79                                __unpark( id, expected );
    8080                                return true;
    8181                        }
  • libcfa/src/concurrency/monitor.cfa

    rae2c27a rc76bd34  
    8989        __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    9090
    91         if( !this->owner ) {
     91        if( unlikely(0 != (0x1 & (uintptr_t)this->owner)) ) {
     92                abort( "Attempt by thread \"%.256s\" (%p) to access joined monitor %p.", thrd->self_cor.name, thrd, this );
     93        }
     94        else if( !this->owner ) {
    9295                // No one has the monitor, just take it
    9396                __set_owner( this, thrd );
     
    119122
    120123                unlock( this->lock );
    121                 park( __cfaabi_dbg_ctx );
     124                park();
    122125
    123126                __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
     
    137140}
    138141
    139 static void __dtor_enter( $monitor * this, fptr_t func ) {
     142static void __dtor_enter( $monitor * this, fptr_t func, bool join ) {
    140143        // Lock the monitor spinlock
    141144        lock( this->lock __cfaabi_dbg_ctx2 );
     
    157160                return;
    158161        }
    159         else if( this->owner == thrd) {
     162        else if( this->owner == thrd && !join) {
    160163                // We already have the monitor... but where about to destroy it so the nesting will fail
    161164                // Abort!
    162165                abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.", this, thrd->self_cor.name, thrd );
     166        }
     167        // SKULLDUGGERY: join will act as a dtor so it would normally trigger to above check
     168        // to avoid that it sets the owner to the special value thrd | 1p before exiting
     169        else if( this->owner == ($thread*)(1 | (uintptr_t)thrd) ) {
     170                // restore the owner and just return
     171                __cfaabi_dbg_print_safe( "Kernel : Destroying free mon %p\n", this);
     172
     173                // No one has the monitor, just take it
     174                this->owner = thrd;
     175
     176                verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     177
     178                unlock( this->lock );
     179                return;
    163180        }
    164181
     
    184201                // Release the next thread
    185202                /* paranoid */ verifyf( urgent->owner->waiting_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
    186                 unpark( urgent->owner->waiting_thread __cfaabi_dbg_ctx2 );
     203                unpark( urgent->owner->waiting_thread );
    187204
    188205                // Park current thread waiting
    189                 park( __cfaabi_dbg_ctx );
     206                park();
    190207
    191208                // Some one was waiting for us, enter
     
    205222
    206223                // Park current thread waiting
    207                 park( __cfaabi_dbg_ctx );
     224                park();
    208225
    209226                /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     
    247264        //We need to wake-up the thread
    248265        /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this );
    249         unpark( new_owner __cfaabi_dbg_ctx2 );
     266        unpark( new_owner );
    250267}
    251268
    252269// Leave single monitor for the last time
    253 void __dtor_leave( $monitor * this ) {
     270void __dtor_leave( $monitor * this, bool join ) {
    254271        __cfaabi_dbg_debug_do(
    255272                if( TL_GET( this_thread ) != this->owner ) {
    256273                        abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
    257274                }
    258                 if( this->recursion != 1 ) {
     275                if( this->recursion != 1  && !join ) {
    259276                        abort( "Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
    260277                }
    261278        )
     279
     280        this->owner = ($thread*)(1 | (uintptr_t)this->owner);
    262281}
    263282
     
    307326}
    308327
     328// Join a thread
     329forall( dtype T | is_thread(T) )
     330T & join( T & this ) {
     331        $monitor *    m = get_monitor(this);
     332        void (*dtor)(T& mutex this) = ^?{};
     333        monitor_dtor_guard_t __guard = { &m, (fptr_t)dtor, true };
     334        {
     335                return this;
     336        }
     337}
     338
    309339// Enter multiple monitor
    310340// relies on the monitor array being sorted
     
    366396// Ctor for monitor guard
    367397// Sorts monitors before entering
    368 void ?{}( monitor_dtor_guard_t & this, $monitor * m [], fptr_t func ) {
     398void ?{}( monitor_dtor_guard_t & this, $monitor * m [], fptr_t func, bool join ) {
    369399        // optimization
    370400        $thread * thrd = TL_GET( this_thread );
     
    376406        this.prev = thrd->monitors;
    377407
     408        // Save whether we are in a join or not
     409        this.join = join;
     410
    378411        // Update thread context (needed for conditions)
    379412        (thrd->monitors){m, 1, func};
    380413
    381         __dtor_enter( this.m, func );
     414        __dtor_enter( this.m, func, join );
    382415}
    383416
     
    385418void ^?{}( monitor_dtor_guard_t & this ) {
    386419        // Leave the monitors in order
    387         __dtor_leave( this.m );
     420        __dtor_leave( this.m, this.join );
    388421
    389422        // Restore thread context
     
    460493        // Wake the threads
    461494        for(int i = 0; i < thread_count; i++) {
    462                 unpark( threads[i] __cfaabi_dbg_ctx2 );
     495                unpark( threads[i] );
    463496        }
    464497
    465498        // Everything is ready to go to sleep
    466         park( __cfaabi_dbg_ctx );
     499        park();
    467500
    468501        // We are back, restore the owners and recursions
     
    542575
    543576        // unpark the thread we signalled
    544         unpark( signallee __cfaabi_dbg_ctx2 );
     577        unpark( signallee );
    545578
    546579        //Everything is ready to go to sleep
    547         park( __cfaabi_dbg_ctx );
     580        park();
    548581
    549582
     
    646679
    647680                                // unpark the thread we signalled
    648                                 unpark( next __cfaabi_dbg_ctx2 );
     681                                unpark( next );
    649682
    650683                                //Everything is ready to go to sleep
    651                                 park( __cfaabi_dbg_ctx );
     684                                park();
    652685
    653686                                // We are back, restore the owners and recursions
     
    691724
    692725        //Everything is ready to go to sleep
    693         park( __cfaabi_dbg_ctx );
     726        park();
    694727
    695728
  • libcfa/src/concurrency/monitor.hfa

    rae2c27a rc76bd34  
    5353        $monitor *    m;
    5454        __monitor_group_t prev;
     55        bool join;
    5556};
    5657
    57 void ?{}( monitor_dtor_guard_t & this, $monitor ** m, void (*func)() );
     58void ?{}( monitor_dtor_guard_t & this, $monitor ** m, void (*func)(), bool join );
    5859void ^?{}( monitor_dtor_guard_t & this );
    5960
  • libcfa/src/concurrency/mutex.cfa

    rae2c27a rc76bd34  
    4242                append( blocked_threads, kernelTLS.this_thread );
    4343                unlock( lock );
    44                 park( __cfaabi_dbg_ctx );
     44                park();
    4545        }
    4646        else {
     
    6565        this.is_locked = (this.blocked_threads != 0);
    6666        unpark(
    67                 pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2
     67                pop_head( this.blocked_threads )
    6868        );
    6969        unlock( this.lock );
     
    9797                append( blocked_threads, kernelTLS.this_thread );
    9898                unlock( lock );
    99                 park( __cfaabi_dbg_ctx );
     99                park();
    100100        }
    101101}
     
    124124                owner = thrd;
    125125                recursion_count = (thrd ? 1 : 0);
    126                 unpark( thrd __cfaabi_dbg_ctx2 );
     126                unpark( thrd );
    127127        }
    128128        unlock( lock );
     
    142142        lock( lock __cfaabi_dbg_ctx2 );
    143143        unpark(
    144                 pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2
     144                pop_head( this.blocked_threads )
    145145        );
    146146        unlock( lock );
     
    151151        while(this.blocked_threads) {
    152152                unpark(
    153                         pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2
     153                        pop_head( this.blocked_threads )
    154154                );
    155155        }
     
    161161        append( this.blocked_threads, kernelTLS.this_thread );
    162162        unlock( this.lock );
    163         park( __cfaabi_dbg_ctx );
     163        park();
    164164}
    165165
     
    170170        unlock(l);
    171171        unlock(this.lock);
    172         park( __cfaabi_dbg_ctx );
     172        park();
    173173        lock(l);
    174174}
  • libcfa/src/concurrency/preemption.cfa

    rae2c27a rc76bd34  
    274274                kernelTLS.this_stats = this->curr_cluster->stats;
    275275        #endif
    276         __unpark( id, this __cfaabi_dbg_ctx2 );
     276        __unpark( id, this );
    277277}
    278278
     
    411411static void * alarm_loop( __attribute__((unused)) void * args ) {
    412412        __processor_id_t id;
     413        id.full_proc = false;
    413414        id.id = doregister(&id);
    414415
  • libcfa/src/concurrency/thread.cfa

    rae2c27a rc76bd34  
    3939        link.prev = 0p;
    4040        link.preferred = -1;
     41        #if defined( __CFA_WITH_VERIFY__ )
     42                canary = 0x0D15EA5E0D15EA5E;
     43        #endif
    4144
    4245        node.next = 0p;
     
    4851
    4952void ^?{}($thread& this) with( this ) {
     53        #if defined( __CFA_WITH_VERIFY__ )
     54                canary = 0xDEADDEADDEADDEAD;
     55        #endif
    5056        unregister(curr_cluster, this);
    5157        ^self_cor{};
  • libcfa/src/concurrency/thread.hfa

    rae2c27a rc76bd34  
    8888//----------
    8989// Park thread: block until corresponding call to unpark, won't block if unpark is already called
    90 void park( __cfaabi_dbg_ctx_param );
     90void park( void );
    9191
    9292//----------
    9393// Unpark a thread, if the thread is already blocked, schedule it
    9494//                  if the thread is not yet block, signal that it should rerun immediately
    95 void unpark( $thread * this __cfaabi_dbg_ctx_param2 );
     95void unpark( $thread * this );
    9696
    9797forall( dtype T | is_thread(T) )
    98 static inline void unpark( T & this __cfaabi_dbg_ctx_param2 ) { if(!&this) return; unpark( get_thread( this ) __cfaabi_dbg_ctx_fwd2 );}
     98static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ) );}
    9999
    100100//----------
     
    106106void sleep( Duration duration );
    107107
     108//----------
     109// join
     110forall( dtype T | is_thread(T) )
     111T & join( T & this );
     112
    108113// Local Variables: //
    109114// mode: c //
  • libcfa/src/exception.h

    rae2c27a rc76bd34  
    7676// implemented in the .c file either so they all have to be inline.
    7777
    78 trait is_exception(dtype T) {
     78trait is_exception(dtype exceptT) {
    7979        /* The first field must be a pointer to a virtual table.
    8080         * That virtual table must be a decendent of the base exception virtual tab$
    8181         */
    82         void mark_exception(T *);
     82        void mark_exception(exceptT *);
    8383        // This is never used and should be a no-op.
    8484};
    8585
    86 trait is_termination_exception(dtype T | is_exception(T)) {
    87         void defaultTerminationHandler(T &);
     86trait is_termination_exception(dtype exceptT | is_exception(exceptT)) {
     87        void defaultTerminationHandler(exceptT &);
    8888};
    8989
    90 trait is_resumption_exception(dtype T | is_exception(T)) {
    91         void defaultResumptionHandler(T &);
     90trait is_resumption_exception(dtype exceptT | is_exception(exceptT)) {
     91        void defaultResumptionHandler(exceptT &);
    9292};
    9393
    94 forall(dtype T | is_termination_exception(T))
    95 static inline void $throw(T & except) {
     94forall(dtype exceptT | is_termination_exception(exceptT))
     95static inline void $throw(exceptT & except) {
    9696        __cfaehm_throw_terminate(
    9797                (exception_t *)&except,
     
    100100}
    101101
    102 forall(dtype T | is_resumption_exception(T))
    103 static inline void $throwResume(T & except) {
     102forall(dtype exceptT | is_resumption_exception(exceptT))
     103static inline void $throwResume(exceptT & except) {
    104104        __cfaehm_throw_resume(
    105105                (exception_t *)&except,
     
    108108}
    109109
    110 forall(dtype T | is_exception(T))
    111 static inline void cancel_stack(T & except) __attribute__((noreturn)) {
     110forall(dtype exceptT | is_exception(exceptT))
     111static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) {
    112112        __cfaehm_cancel_stack( (exception_t *)&except );
    113113}
    114114
    115 forall(dtype T | is_exception(T))
    116 static inline void defaultTerminationHandler(T & except) {
     115forall(dtype exceptT | is_exception(exceptT))
     116static inline void defaultTerminationHandler(exceptT & except) {
    117117        return cancel_stack( except );
    118118}
    119119
    120 forall(dtype T | is_exception(T))
    121 static inline void defaultResumptionHandler(T & except) {
     120forall(dtype exceptT | is_exception(exceptT))
     121static inline void defaultResumptionHandler(exceptT & except) {
    122122        throw except;
    123123}
  • libcfa/src/exception.hfa

    rae2c27a rc76bd34  
    192192                size_t size; \
    193193                void (*copy)(exception_name * this, exception_name * other); \
    194                 void (*free)(exception_name & this); \
     194                void (*^?{})(exception_name & this); \
    195195                const char * (*msg)(exception_name * this); \
    196196                _CLOSE
     
    213213                size_t size; \
    214214                void (*copy)(exception_name parameters * this, exception_name parameters * other); \
    215                 void (*free)(exception_name parameters & this); \
     215                void (*^?{})(exception_name parameters & this); \
    216216                const char * (*msg)(exception_name parameters * this); \
    217217                _CLOSE
  • libcfa/src/heap.cfa

    rae2c27a rc76bd34  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Sep  3 16:22:54 2020
    13 // Update Count     : 943
     12// Last Modified On : Mon Sep  7 22:17:46 2020
     13// Update Count     : 957
    1414//
    1515
     
    889889                size_t bsize, oalign;
    890890                headers( "resize", oaddr, header, freeElem, bsize, oalign );
    891 
    892891                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     892
    893893                // same size, DO NOT preserve STICKY PROPERTIES.
    894                 if ( oalign <= libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
     894                if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    895895                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
    896896                        header->kind.real.size = size;                          // reset allocation size
     
    931931                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    932932                size_t osize = header->kind.real.size;                  // old allocation size
    933                 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
    934           if ( unlikely( size <= odsize ) && size > odsize / 2 ) { // allow up to 50% wasted storage
     933                bool ozfill = (header->kind.real.blockSize & 2); // old allocation zero filled
     934          if ( unlikely( size <= odsize ) && odsize <= size * 2 ) { // allow up to 50% wasted storage
    935935                        header->kind.real.size = size;                          // reset allocation size
    936936                        if ( unlikely( ozfill ) && size > osize ) {     // previous request zero fill and larger ?
     
    947947
    948948                void * naddr;
    949                 if ( likely( oalign <= libAlign() ) ) {                 // previous request not aligned ?
     949                if ( likely( oalign == libAlign() ) ) {                 // previous request not aligned ?
    950950                        naddr = mallocNoStats( size );                          // create new area
    951951                } else {
     
    12311231        } // if
    12321232
    1233         // Attempt to reuse existing storage.
     1233        // Attempt to reuse existing alignment.
    12341234        HeapManager.Storage.Header * header = headerAddr( oaddr );
    1235         bool isFakeHeader = header->kind.fake.alignment & 1 == 1;       // old fake header ?
    1236         if ( unlikely ( ( isFakeHeader &&
    1237                                  (uintptr_t)oaddr % nalign == 0 &&                              // lucky match ?
    1238                                  header->kind.fake.alignment <= nalign &&               // ok to leave LSB at 1
    1239                                  nalign <= 128 )                                                                // not too much alignment storage wasted ?
    1240                         ||   ( (!isFakeHeader) &&                                                       // old real header ( aligned on libAlign ) ?
    1241                                  nalign == libAlign() ) ) ) {                                   // new alignment also on libAlign
    1242 
    1243                 HeapManager.FreeHeader * freeElem;
    1244                 size_t bsize, oalign;
    1245                 headers( "resize", oaddr, header, freeElem, bsize, oalign );
    1246                 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    1247 
    1248                 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
    1249                         if ( isFakeHeader ) {
     1235        bool isFakeHeader = header->kind.fake.alignment & 1; // old fake header ?
     1236        size_t oalign;
     1237        if ( isFakeHeader ) {
     1238                oalign = header->kind.fake.alignment & -2;              // old alignment
     1239                if ( (uintptr_t)oaddr % nalign == 0                             // lucky match ?
     1240                         && ( oalign <= nalign                                          // going down
     1241                                  || (oalign >= nalign && oalign <= 256) ) // little alignment storage wasted ?
     1242                        ) {
     1243                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
     1244                        HeapManager.FreeHeader * freeElem;
     1245                        size_t bsize, oalign;
     1246                        headers( "resize", oaddr, header, freeElem, bsize, oalign );
     1247                        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1248
     1249                        if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
    12501250                                headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1251                         }
    1252 
    1253                         header->kind.real.blockSize &= -2;              // turn off 0 fill
    1254                         header->kind.real.size = size;                  // reset allocation size
    1255                         return oaddr;
    1256                 } // if
     1251
     1252                                header->kind.real.blockSize &= -2;              // turn off 0 fill
     1253                                header->kind.real.size = size;                  // reset allocation size
     1254                                return oaddr;
     1255                        } // if
     1256                } // if
     1257        } else if ( ! isFakeHeader                                                      // old real header (aligned on libAlign) ?
     1258                                && nalign == libAlign() ) {                             // new alignment also on libAlign => no fake header needed
     1259                return resize( oaddr, size );                                   // duplicate special case checks
    12571260        } // if
    12581261
     
    12841287        } // if
    12851288
    1286         HeapManager.Storage.Header * header;
    1287         HeapManager.FreeHeader * freeElem;
    1288         size_t bsize, oalign;
    1289         headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    1290 
    1291         // Attempt to reuse existing storage.
    1292         bool isFakeHeader = header->kind.fake.alignment & 1 == 1;       // old fake header ?
    1293         if ( unlikely ( ( isFakeHeader &&
    1294                                  (uintptr_t)oaddr % nalign == 0 &&                              // lucky match ?
    1295                                  header->kind.fake.alignment <= nalign &&               // ok to leave LSB at 1
    1296                                  nalign <= 128 )                                                                // not too much alignment storage wasted ?
    1297                         ||   ( (!isFakeHeader) &&                                                       // old real header ( aligned on libAlign ) ?
    1298                                  nalign == libAlign() ) ) ) {                                   // new alignment also on libAlign
    1299 
    1300                 if ( isFakeHeader ) {
     1289        // Attempt to reuse existing alignment.
     1290        HeapManager.Storage.Header * header = headerAddr( oaddr );
     1291        bool isFakeHeader = header->kind.fake.alignment & 1; // old fake header ?
     1292        size_t oalign;
     1293        if ( isFakeHeader ) {
     1294                oalign = header->kind.fake.alignment & -2;              // old alignment
     1295                if ( (uintptr_t)oaddr % nalign == 0                             // lucky match ?
     1296                         && ( oalign <= nalign                                          // going down
     1297                                  || (oalign >= nalign && oalign <= 256) ) // little alignment storage wasted ?
     1298                        ) {
    13011299                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1302                 }
    1303                 return realloc( oaddr, size );
    1304 
    1305         } // if
    1306 
    1307         // change size and copy old content to new storage
     1300                        return realloc( oaddr, size );                          // duplicate alignment and special case checks
     1301                } // if
     1302        } else if ( ! isFakeHeader                                                      // old real header (aligned on libAlign) ?
     1303                                && nalign == libAlign() )                               // new alignment also on libAlign => no fake header needed
     1304                return realloc( oaddr, size );                                  // duplicate alignment and special case checks
    13081305
    13091306        #ifdef __STATISTICS__
     
    13121309        #endif // __STATISTICS__
    13131310
     1311        HeapManager.FreeHeader * freeElem;
     1312        size_t bsize;
     1313        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
     1314
     1315        // change size and copy old content to new storage
     1316
    13141317        size_t osize = header->kind.real.size;                          // old allocation size
    1315         bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
     1318        bool ozfill = (header->kind.real.blockSize & 2);        // old allocation zero filled
    13161319
    13171320        void * naddr = memalignNoStats( nalign, size );         // create new aligned area
  • libcfa/src/limits.cfa

    rae2c27a rc76bd34  
    1010// Created On       : Wed Apr  6 18:06:52 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  1 16:22:51 2018
    13 // Update Count     : 74
     12// Last Modified On : Wed Sep 30 22:56:32 2020
     13// Update Count     : 76
    1414//
    1515
     
    2323// Integral Constants
    2424
    25 const signed char MIN = SCHAR_MIN;
    26 const unsigned char MIN = 0;
    27 const short int MIN = SHRT_MIN;
    28 const unsigned short int MIN = 0;
    29 const int MIN = INT_MIN;
    30 const unsigned int MIN = 0;
    31 const long int MIN = LONG_MIN;
    32 const unsigned long int MIN = 0;
    33 const long long int MIN = LLONG_MIN;
    34 const unsigned long long int MIN = 0;
     25signed char MIN = SCHAR_MIN;
     26unsigned char MIN = 0;
     27short int MIN = SHRT_MIN;
     28unsigned short int MIN = 0;
     29int MIN = INT_MIN;
     30unsigned int MIN = 0;
     31long int MIN = LONG_MIN;
     32unsigned long int MIN = 0;
     33long long int MIN = LLONG_MIN;
     34unsigned long long int MIN = 0;
    3535
    36 const signed char MAX = SCHAR_MAX;
    37 const unsigned char MAX = UCHAR_MAX;
    38 const short int MAX = SHRT_MAX;
    39 const unsigned short int MAX = USHRT_MAX;
    40 const int MAX = INT_MAX;
    41 const unsigned int MAX = UINT_MAX;
    42 const long int MAX = LONG_MAX;
    43 const unsigned long int MAX = ULONG_MAX;
    44 const long long int MAX = LLONG_MAX;
    45 const unsigned long long int MAX = ULLONG_MAX;
     36signed char MAX = SCHAR_MAX;
     37unsigned char MAX = UCHAR_MAX;
     38short int MAX = SHRT_MAX;
     39unsigned short int MAX = USHRT_MAX;
     40int MAX = INT_MAX;
     41unsigned int MAX = UINT_MAX;
     42long int MAX = LONG_MAX;
     43unsigned long int MAX = ULONG_MAX;
     44long long int MAX = LLONG_MAX;
     45unsigned long long int MAX = ULLONG_MAX;
    4646
    4747// Floating-Point Constants
    4848
    49 const float MIN = FLT_MIN;
    50 const double MIN = DBL_MIN;
    51 const long double MIN = LDBL_MIN;
    52 const float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
    53 const double _Complex MIN = DBL_MIN +  DBL_MIN * I;
    54 const long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
     49float MIN = FLT_MIN;
     50double MIN = DBL_MIN;
     51long double MIN = LDBL_MIN;
     52float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
     53double _Complex MIN = DBL_MIN +  DBL_MIN * I;
     54long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
    5555
    56 const float MAX = FLT_MAX;
    57 const double MAX = DBL_MAX;
    58 const long double MAX = LDBL_MAX;
    59 const float _Complex MAX = FLT_MAX + FLT_MAX * I;
    60 const double _Complex MAX = DBL_MAX + DBL_MAX * I;
    61 const long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
     56float MAX = FLT_MAX;
     57double MAX = DBL_MAX;
     58long double MAX = LDBL_MAX;
     59float _Complex MAX = FLT_MAX + FLT_MAX * I;
     60double _Complex MAX = DBL_MAX + DBL_MAX * I;
     61long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
    6262
    63 const float PI = (float)M_PI;                                                   // pi
    64 const float PI_2 = (float)M_PI_2;                                               // pi / 2
    65 const float PI_4 = (float)M_PI_4;                                               // pi / 4
    66 const float _1_PI = (float)M_1_PI;                                              // 1 / pi
    67 const float _2_PI = (float)M_2_PI;                                              // 2 / pi
    68 const float _2_SQRT_PI = (float)M_2_SQRTPI;                             // 2 / sqrt(pi)
     63float PI = (float)M_PI;                                                                 // pi
     64float PI_2 = (float)M_PI_2;                                                             // pi / 2
     65float PI_4 = (float)M_PI_4;                                                             // pi / 4
     66float _1_PI = (float)M_1_PI;                                                    // 1 / pi
     67float _2_PI = (float)M_2_PI;                                                    // 2 / pi
     68float _2_SQRT_PI = (float)M_2_SQRTPI;                                   // 2 / sqrt(pi)
    6969
    70 const double PI = M_PI;                                                                 // pi
    71 const double PI_2 = M_PI_2;                                                             // pi / 2
    72 const double PI_4 = M_PI_4;                                                             // pi / 4
    73 const double _1_PI = M_1_PI;                                                    // 1 / pi
    74 const double _2_PI = M_2_PI;                                                    // 2 / pi
    75 const double _2_SQRT_PI = M_2_SQRTPI;                                   // 2 / sqrt(pi)
     70double PI = M_PI;                                                                               // pi
     71double PI_2 = M_PI_2;                                                                   // pi / 2
     72double PI_4 = M_PI_4;                                                                   // pi / 4
     73double _1_PI = M_1_PI;                                                                  // 1 / pi
     74double _2_PI = M_2_PI;                                                                  // 2 / pi
     75double _2_SQRT_PI = M_2_SQRTPI;                                                 // 2 / sqrt(pi)
    7676
    77 const long double PI = M_PIl;                                                   // pi
    78 const long double PI_2 = M_PI_2l;                                               // pi / 2
    79 const long double PI_4 = M_PI_4l;                                               // pi / 4
    80 const long double _1_PI = M_1_PIl;                                              // 1 / pi
    81 const long double _2_PI = M_2_PIl;                                              // 2 / pi
    82 const long double _2_SQRT_PI = M_2_SQRTPIl;                             // 2 / sqrt(pi)
     77long double PI = M_PIl;                                                                 // pi
     78long double PI_2 = M_PI_2l;                                                             // pi / 2
     79long double PI_4 = M_PI_4l;                                                             // pi / 4
     80long double _1_PI = M_1_PIl;                                                    // 1 / pi
     81long double _2_PI = M_2_PIl;                                                    // 2 / pi
     82long double _2_SQRT_PI = M_2_SQRTPIl;                                   // 2 / sqrt(pi)
    8383
    84 const float _Complex PI = (float)M_PI + 0.0_iF;                 // pi
    85 const float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;             // pi / 2
    86 const float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;             // pi / 4
    87 const float _Complex _1_PI = (float)M_1_PI + 0.0_iF;    // 1 / pi
    88 const float _Complex _2_PI = (float)M_2_PI + 0.0_iF;    // 2 / pi
    89 const float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
     84float _Complex PI = (float)M_PI + 0.0_iF;                               // pi
     85float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;                   // pi / 2
     86float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;                   // pi / 4
     87float _Complex _1_PI = (float)M_1_PI + 0.0_iF;                  // 1 / pi
     88float _Complex _2_PI = (float)M_2_PI + 0.0_iF;                  // 2 / pi
     89float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
    9090
    91 const double _Complex PI = M_PI + 0.0_iD;                               // pi
    92 const double _Complex PI_2 = M_PI_2 + 0.0_iD;                   // pi / 2
    93 const double _Complex PI_4 = M_PI_4 + 0.0_iD;                   // pi / 4
    94 const double _Complex _1_PI = M_1_PI + 0.0_iD;                  // 1 / pi
    95 const double _Complex _2_PI = M_2_PI + 0.0_iD;                  // 2 / pi
    96 const double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD; // 2 / sqrt(pi)
     91double _Complex PI = M_PI + 0.0_iD;                                             // pi
     92double _Complex PI_2 = M_PI_2 + 0.0_iD;                                 // pi / 2
     93double _Complex PI_4 = M_PI_4 + 0.0_iD;                                 // pi / 4
     94double _Complex _1_PI = M_1_PI + 0.0_iD;                                // 1 / pi
     95double _Complex _2_PI = M_2_PI + 0.0_iD;                                // 2 / pi
     96double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD;               // 2 / sqrt(pi)
    9797
    98 const long double _Complex PI = M_PIl + 0.0_iL;                 // pi
    99 const long double _Complex PI_2 = M_PI_2l + 0.0_iL;             // pi / 2
    100 const long double _Complex PI_4 = M_PI_4l + 0.0_iL;             // pi / 4
    101 const long double _Complex _1_PI = M_1_PIl + 0.0_iL;    // 1 / pi
    102 const long double _Complex _2_PI = M_2_PIl + 0.0_iL;    // 2 / pi
    103 const long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
     98long double _Complex PI = M_PIl + 0.0_iL;                               // pi
     99long double _Complex PI_2 = M_PI_2l + 0.0_iL;                   // pi / 2
     100long double _Complex PI_4 = M_PI_4l + 0.0_iL;                   // pi / 4
     101long double _Complex _1_PI = M_1_PIl + 0.0_iL;                  // 1 / pi
     102long double _Complex _2_PI = M_2_PIl + 0.0_iL;                  // 2 / pi
     103long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
    104104
    105 const float E = (float)M_E;                                                             // e
    106 const float LOG2_E = (float)M_LOG2E;                                    // log_2(e)
    107 const float LOG10_E = (float)M_LOG10E;                                  // log_10(e)
    108 const float LN_2 = (float)M_LN2;                                                // log_e(2)
    109 const float LN_10 = (float)M_LN10;                                              // log_e(10)
    110 const float SQRT_2 = (float)M_SQRT2;                                    // sqrt(2)
    111 const float _1_SQRT_2 = (float)M_SQRT1_2;                               // 1 / sqrt(2)
     105float E = (float)M_E;                                                                   // e
     106float LOG2_E = (float)M_LOG2E;                                                  // log_2(e)
     107float LOG10_E = (float)M_LOG10E;                                                // log_10(e)
     108float LN_2 = (float)M_LN2;                                                              // log_e(2)
     109float LN_10 = (float)M_LN10;                                                    // log_e(10)
     110float SQRT_2 = (float)M_SQRT2;                                                  // sqrt(2)
     111float _1_SQRT_2 = (float)M_SQRT1_2;                                             // 1 / sqrt(2)
    112112
    113 const double E = M_E;                                                                   // e
    114 const double LOG2_E = M_LOG2E;                                                  // log_2(e)
    115 const double LOG10_E = M_LOG10E;                                                // log_10(e)
    116 const double LN_2 = M_LN2;                                                              // log_e(2)
    117 const double LN_10 = M_LN10;                                                    // log_e(10)
    118 const double SQRT_2 = M_SQRT2;                                                  // sqrt(2)
    119 const double _1_SQRT_2 = M_SQRT1_2;                                             // 1 / sqrt(2)
     113double E = M_E;                                                                                 // e
     114double LOG2_E = M_LOG2E;                                                                // log_2(e)
     115double LOG10_E = M_LOG10E;                                                              // log_10(e)
     116double LN_2 = M_LN2;                                                                    // log_e(2)
     117double LN_10 = M_LN10;                                                                  // log_e(10)
     118double SQRT_2 = M_SQRT2;                                                                // sqrt(2)
     119double _1_SQRT_2 = M_SQRT1_2;                                                   // 1 / sqrt(2)
    120120
    121 const long double E = M_El;                                                             // e
    122 const long double LOG2_E = M_LOG2El;                                    // log_2(e)
    123 const long double LOG10_E = M_LOG10El;                                  // log_10(e)
    124 const long double LN_2 = M_LN2l;                                                // log_e(2)
    125 const long double LN_10 = M_LN10l;                                              // log_e(10)
    126 const long double SQRT_2 = M_SQRT2l;                                    // sqrt(2)
    127 const long double _1_SQRT_2 = M_SQRT1_2l;                               // 1 / sqrt(2)
     121long double E = M_El;                                                                   // e
     122long double LOG2_E = M_LOG2El;                                                  // log_2(e)
     123long double LOG10_E = M_LOG10El;                                                // log_10(e)
     124long double LN_2 = M_LN2l;                                                              // log_e(2)
     125long double LN_10 = M_LN10l;                                                    // log_e(10)
     126long double SQRT_2 = M_SQRT2l;                                                  // sqrt(2)
     127long double _1_SQRT_2 = M_SQRT1_2l;                                             // 1 / sqrt(2)
    128128
    129 const float _Complex E = M_E + 0.0_iF;                                  // e
    130 const float _Complex LOG2_E = M_LOG2E + 0.0_iF;                 // log_2(e)
    131 const float _Complex LOG10_E = M_LOG10E + 0.0_iF;               // log_10(e)
    132 const float _Complex LN_2 = M_LN2 + 0.0_iF;                             // log_e(2)
    133 const float _Complex LN_10 = M_LN10 + 0.0_iF;                   // log_e(10)
    134 const float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;                 // sqrt(2)
    135 const float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;    // 1 / sqrt(2)
     129float _Complex E = M_E + 0.0_iF;                                                // e
     130float _Complex LOG2_E = M_LOG2E + 0.0_iF;                               // log_2(e)
     131float _Complex LOG10_E = M_LOG10E + 0.0_iF;                             // log_10(e)
     132float _Complex LN_2 = M_LN2 + 0.0_iF;                                   // log_e(2)
     133float _Complex LN_10 = M_LN10 + 0.0_iF;                                 // log_e(10)
     134float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;                               // sqrt(2)
     135float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;                  // 1 / sqrt(2)
    136136
    137 const double _Complex E = M_E + 0.0_iD;                                 // e
    138 const double _Complex LOG2_E = M_LOG2E + 0.0_iD;                // log_2(e)
    139 const double _Complex LOG10_E = M_LOG10E + 0.0_iD;              // log_10(e)
    140 const double _Complex LN_2 = M_LN2 + 0.0_iD;                    // log_e(2)
    141 const double _Complex LN_10 = M_LN10 + 0.0_iD;                  // log_e(10)
    142 const double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;                // sqrt(2)
    143 const double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;   // 1 / sqrt(2)
     137double _Complex E = M_E + 0.0_iD;                                               // e
     138double _Complex LOG2_E = M_LOG2E + 0.0_iD;                              // log_2(e)
     139double _Complex LOG10_E = M_LOG10E + 0.0_iD;                    // log_10(e)
     140double _Complex LN_2 = M_LN2 + 0.0_iD;                                  // log_e(2)
     141double _Complex LN_10 = M_LN10 + 0.0_iD;                                // log_e(10)
     142double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;                              // sqrt(2)
     143double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;                 // 1 / sqrt(2)
    144144
    145 const long double _Complex E = M_El + 0.0_iL;                   // e
    146 const long double _Complex LOG2_E = M_LOG2El + 0.0_iL;  // log_2(e)
    147 const long double _Complex LOG10_E = M_LOG10El + 0.0_iL; // log_10(e)
    148 const long double _Complex LN_2 = M_LN2l + 0.0_iL;              // log_e(2)
    149 const long double _Complex LN_10 = M_LN10l + 0.0_iL;    // log_e(10)
    150 const long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;  // sqrt(2)
    151 const long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL; // 1 / sqrt(2)
     145long double _Complex E = M_El + 0.0_iL;                                 // e
     146long double _Complex LOG2_E = M_LOG2El + 0.0_iL;                // log_2(e)
     147long double _Complex LOG10_E = M_LOG10El + 0.0_iL;              // log_10(e)
     148long double _Complex LN_2 = M_LN2l + 0.0_iL;                    // log_e(2)
     149long double _Complex LN_10 = M_LN10l + 0.0_iL;                  // log_e(10)
     150long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;                // sqrt(2)
     151long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL;   // 1 / sqrt(2)
    152152
    153153// Local Variables: //
  • libcfa/src/limits.hfa

    rae2c27a rc76bd34  
    1010// Created On       : Wed Apr  6 18:06:52 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  1 16:20:54 2018
    13 // Update Count     : 13
     12// Last Modified On : Wed Sep 30 22:56:35 2020
     13// Update Count     : 15
    1414//
    1515
     
    1818// Integral Constants
    1919
    20 extern const signed char MIN;
    21 extern const unsigned char MIN;
    22 extern const short int MIN;
    23 extern const unsigned short int MIN;
    24 extern const int MIN;
    25 extern const unsigned int MIN;
    26 extern const long int MIN;
    27 extern const unsigned long int MIN;
    28 extern const long long int MIN;
    29 extern const unsigned long long int MIN;
     20extern signed char MIN;
     21extern unsigned char MIN;
     22extern short int MIN;
     23extern unsigned short int MIN;
     24extern int MIN;
     25extern unsigned int MIN;
     26extern long int MIN;
     27extern unsigned long int MIN;
     28extern long long int MIN;
     29extern unsigned long long int MIN;
    3030
    31 extern const signed char MAX;
    32 extern const unsigned char MAX;
    33 extern const short int MAX;
    34 extern const unsigned short int MAX;
    35 extern const int MAX;
    36 extern const unsigned int MAX;
    37 extern const long int MAX;
    38 extern const unsigned long int MAX;
    39 extern const long long int MAX;
    40 extern const unsigned long long int MAX;
     31extern signed char MAX;
     32extern unsigned char MAX;
     33extern short int MAX;
     34extern unsigned short int MAX;
     35extern int MAX;
     36extern unsigned int MAX;
     37extern long int MAX;
     38extern unsigned long int MAX;
     39extern long long int MAX;
     40extern unsigned long long int MAX;
    4141
    4242// Floating-Point Constants
    4343
    44 extern const float MIN;
    45 extern const double MIN;
    46 extern const long double MIN;
    47 extern const float _Complex MIN;
    48 extern const double _Complex MIN;
    49 extern const long double _Complex MIN;
     44extern float MIN;
     45extern double MIN;
     46extern long double MIN;
     47extern float _Complex MIN;
     48extern double _Complex MIN;
     49extern long double _Complex MIN;
    5050
    51 extern const float MAX;
    52 extern const double MAX;
    53 extern const long double MAX;
    54 extern const float _Complex MAX;
    55 extern const double _Complex MAX;
    56 extern const long double _Complex MAX;
     51extern float MAX;
     52extern double MAX;
     53extern long double MAX;
     54extern float _Complex MAX;
     55extern double _Complex MAX;
     56extern long double _Complex MAX;
    5757
    58 extern const float PI;                                                                  // pi
    59 extern const float PI_2;                                                                // pi / 2
    60 extern const float PI_4;                                                                // pi / 4
    61 extern const float _1_PI;                                                               // 1 / pi
    62 extern const float _2_PI;                                                               // 2 / pi
    63 extern const float _2_SQRT_PI;                                                  // 2 / sqrt(pi)
     58extern float PI;                                                                                // pi
     59extern float PI_2;                                                                              // pi / 2
     60extern float PI_4;                                                                              // pi / 4
     61extern float _1_PI;                                                                             // 1 / pi
     62extern float _2_PI;                                                                             // 2 / pi
     63extern float _2_SQRT_PI;                                                                // 2 / sqrt(pi)
    6464
    65 extern const double PI;                                                                 // pi
    66 extern const double PI_2;                                                               // pi / 2
    67 extern const double PI_4;                                                               // pi / 4
    68 extern const double _1_PI;                                                              // 1 / pi
    69 extern const double _2_PI;                                                              // 2 / pi
    70 extern const double _2_SQRT_PI;                                                 // 2 / sqrt(pi)
     65extern double PI;                                                                               // pi
     66extern double PI_2;                                                                             // pi / 2
     67extern double PI_4;                                                                             // pi / 4
     68extern double _1_PI;                                                                    // 1 / pi
     69extern double _2_PI;                                                                    // 2 / pi
     70extern double _2_SQRT_PI;                                                               // 2 / sqrt(pi)
    7171
    72 extern const long double PI;                                                    // pi
    73 extern const long double PI_2;                                                  // pi / 2
    74 extern const long double PI_4;                                                  // pi / 4
    75 extern const long double _1_PI;                                                 // 1 / pi
    76 extern const long double _2_PI;                                                 // 2 / pi
    77 extern const long double _2_SQRT_PI;                                    // 2 / sqrt(pi)
     72extern long double PI;                                                                  // pi
     73extern long double PI_2;                                                                // pi / 2
     74extern long double PI_4;                                                                // pi / 4
     75extern long double _1_PI;                                                               // 1 / pi
     76extern long double _2_PI;                                                               // 2 / pi
     77extern long double _2_SQRT_PI;                                                  // 2 / sqrt(pi)
    7878
    79 extern const float _Complex PI;                                                 // pi
    80 extern const float _Complex PI_2;                                               // pi / 2
    81 extern const float _Complex PI_4;                                               // pi / 4
    82 extern const float _Complex _1_PI;                                              // 1 / pi
    83 extern const float _Complex _2_PI;                                              // 2 / pi
    84 extern const float _Complex _2_SQRT_PI;                                 // 2 / sqrt(pi)
     79extern float _Complex PI;                                                               // pi
     80extern float _Complex PI_2;                                                             // pi / 2
     81extern float _Complex PI_4;                                                             // pi / 4
     82extern float _Complex _1_PI;                                                    // 1 / pi
     83extern float _Complex _2_PI;                                                    // 2 / pi
     84extern float _Complex _2_SQRT_PI;                                               // 2 / sqrt(pi)
    8585
    86 extern const double _Complex PI;                                                // pi
    87 extern const double _Complex PI_2;                                              // pi / 2
    88 extern const double _Complex PI_4;                                              // pi / 4
    89 extern const double _Complex _1_PI;                                             // 1 / pi
    90 extern const double _Complex _2_PI;                                             // 2 / pi
    91 extern const double _Complex _2_SQRT_PI;                                // 2 / sqrt(pi)
     86extern double _Complex PI;                                                              // pi
     87extern double _Complex PI_2;                                                    // pi / 2
     88extern double _Complex PI_4;                                                    // pi / 4
     89extern double _Complex _1_PI;                                                   // 1 / pi
     90extern double _Complex _2_PI;                                                   // 2 / pi
     91extern double _Complex _2_SQRT_PI;                                              // 2 / sqrt(pi)
    9292
    93 extern const long double _Complex PI;                                   // pi
    94 extern const long double _Complex PI_2;                                 // pi / 2
    95 extern const long double _Complex PI_4;                                 // pi / 4
    96 extern const long double _Complex _1_PI;                                // 1 / pi
    97 extern const long double _Complex _2_PI;                                // 2 / pi
    98 extern const long double _Complex _2_SQRT_PI;                   // 2 / sqrt(pi)
     93extern long double _Complex PI;                                                 // pi
     94extern long double _Complex PI_2;                                               // pi / 2
     95extern long double _Complex PI_4;                                               // pi / 4
     96extern long double _Complex _1_PI;                                              // 1 / pi
     97extern long double _Complex _2_PI;                                              // 2 / pi
     98extern long double _Complex _2_SQRT_PI;                                 // 2 / sqrt(pi)
    9999
    100 extern const float E;                                                                   // e
    101 extern const float LOG2_E;                                                              // log_2(e)
    102 extern const float LOG10_E;                                                             // log_10(e)
    103 extern const float LN_2;                                                                // log_e(2)
    104 extern const float LN_10;                                                               // log_e(10)
    105 extern const float SQRT_2;                                                              // sqrt(2)
    106 extern const float _1_SQRT_2;                                                   // 1 / sqrt(2)
     100extern float E;                                                                                 // e
     101extern float LOG2_E;                                                                    // log_2(e)
     102extern float LOG10_E;                                                                   // log_10(e)
     103extern float LN_2;                                                                              // log_e(2)
     104extern float LN_10;                                                                             // log_e(10)
     105extern float SQRT_2;                                                                    // sqrt(2)
     106extern float _1_SQRT_2;                                                                 // 1 / sqrt(2)
    107107
    108 extern const double E;                                                                  // e
    109 extern const double LOG2_E;                                                             // log_2(e)
    110 extern const double LOG10_E;                                                    // log_10(e)
    111 extern const double LN_2;                                                               // log_e(2)
    112 extern const double LN_10;                                                              // log_e(10)
    113 extern const double SQRT_2;                                                             // sqrt(2)
    114 extern const double _1_SQRT_2;                                                  // 1 / sqrt(2)
     108extern double E;                                                                                // e
     109extern double LOG2_E;                                                                   // log_2(e)
     110extern double LOG10_E;                                                                  // log_10(e)
     111extern double LN_2;                                                                             // log_e(2)
     112extern double LN_10;                                                                    // log_e(10)
     113extern double SQRT_2;                                                                   // sqrt(2)
     114extern double _1_SQRT_2;                                                                // 1 / sqrt(2)
    115115
    116 extern const long double E;                                                             // e
    117 extern const long double LOG2_E;                                                // log_2(e)
    118 extern const long double LOG10_E;                                               // log_10(e)
    119 extern const long double LN_2;                                                  // log_e(2)
    120 extern const long double LN_10;                                                 // log_e(10)
    121 extern const long double SQRT_2;                                                // sqrt(2)
    122 extern const long double _1_SQRT_2;                                             // 1/sqrt(2)
     116extern long double E;                                                                   // e
     117extern long double LOG2_E;                                                              // log_2(e)
     118extern long double LOG10_E;                                                             // log_10(e)
     119extern long double LN_2;                                                                // log_e(2)
     120extern long double LN_10;                                                               // log_e(10)
     121extern long double SQRT_2;                                                              // sqrt(2)
     122extern long double _1_SQRT_2;                                                   // 1/sqrt(2)
    123123
    124 extern const float _Complex E;                                                  // e
    125 extern const float _Complex LOG2_E;                                             // log_2(e)
    126 extern const float _Complex LOG10_E;                                    // log_10(e)
    127 extern const float _Complex LN_2;                                               // log_e(2)
    128 extern const float _Complex LN_10;                                              // log_e(10)
    129 extern const float _Complex SQRT_2;                                             // sqrt(2)
    130 extern const float _Complex _1_SQRT_2;                                  // 1 / sqrt(2)
     124extern float _Complex E;                                                                // e
     125extern float _Complex LOG2_E;                                                   // log_2(e)
     126extern float _Complex LOG10_E;                                                  // log_10(e)
     127extern float _Complex LN_2;                                                             // log_e(2)
     128extern float _Complex LN_10;                                                    // log_e(10)
     129extern float _Complex SQRT_2;                                                   // sqrt(2)
     130extern float _Complex _1_SQRT_2;                                                // 1 / sqrt(2)
    131131
    132 extern const double _Complex E;                                                 // e
    133 extern const double _Complex LOG2_E;                                    // log_2(e)
    134 extern const double _Complex LOG10_E;                                   // log_10(e)
    135 extern const double _Complex LN_2;                                              // log_e(2)
    136 extern const double _Complex LN_10;                                             // log_e(10)
    137 extern const double _Complex SQRT_2;                                    // sqrt(2)
    138 extern const double _Complex _1_SQRT_2;                                 // 1 / sqrt(2)
     132extern double _Complex E;                                                               // e
     133extern double _Complex LOG2_E;                                                  // log_2(e)
     134extern double _Complex LOG10_E;                                                 // log_10(e)
     135extern double _Complex LN_2;                                                    // log_e(2)
     136extern double _Complex LN_10;                                                   // log_e(10)
     137extern double _Complex SQRT_2;                                                  // sqrt(2)
     138extern double _Complex _1_SQRT_2;                                               // 1 / sqrt(2)
    139139
    140 extern const long double _Complex E;                                    // e
    141 extern const long double _Complex LOG2_E;                               // log_2(e)
    142 extern const long double _Complex LOG10_E;                              // log_10(e)
    143 extern const long double _Complex LN_2;                                 // log_e(2)
    144 extern const long double _Complex LN_10;                                // log_e(10)
    145 extern const long double _Complex SQRT_2;                               // sqrt(2)
    146 extern const long double _Complex _1_SQRT_2;                    // 1 / sqrt(2)
     140extern long double _Complex E;                                                  // e
     141extern long double _Complex LOG2_E;                                             // log_2(e)
     142extern long double _Complex LOG10_E;                                    // log_10(e)
     143extern long double _Complex LN_2;                                               // log_e(2)
     144extern long double _Complex LN_10;                                              // log_e(10)
     145extern long double _Complex SQRT_2;                                             // sqrt(2)
     146extern long double _Complex _1_SQRT_2;                                  // 1 / sqrt(2)
    147147
    148148// Local Variables: //
  • libcfa/src/parseargs.cfa

    rae2c27a rc76bd34  
    2525#include "limits.hfa"
    2626
    27 extern int cfa_args_argc;
    28 extern char ** cfa_args_argv;
    29 extern char ** cfa_args_envp;
     27extern int cfa_args_argc __attribute__((weak));
     28extern char ** cfa_args_argv __attribute__((weak));
     29extern char ** cfa_args_envp __attribute__((weak));
    3030
    3131static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out)  __attribute__ ((noreturn));
    3232
    3333void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) {
    34         parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left );
     34        if( 0p != &cfa_args_argc ) {
     35                parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left );
     36        }
     37        else {
     38                char * temp = "";
     39                parse_args(0, &temp, options, opt_count, usage, left );
     40        }
    3541}
    3642
Note: See TracChangeset for help on using the changeset viewer.