Changes in / [2d019af:41ca6fa]


Ignore:
Files:
20 added
16 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    r2d019af r41ca6fa  
    148148def test() {
    149149        try {
     150                // Print potential limits before testing
     151                // in case jenkins messes with them
     152                sh 'free -h'
     153                sh 'ulimit -a'
     154
    150155                Tools.BuildStage('Test: short', !Settings.RunAllTests) {
    151156                        dir (BuildDir) {
  • benchmark/Makefile.am

    r2d019af r41ca6fa  
    502502
    503503compile-io$(EXEEXT):
    504         $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io1.cfa
     504        $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io/io.cfa
    505505
    506506compile-monitor$(EXEEXT):
  • doc/LaTeXmacros/lstlang.sty

    r2d019af r41ca6fa  
    88%% Created On       : Sat May 13 16:34:42 2017
    99%% Last Modified By : Peter A. Buhr
    10 %% Last Modified On : Wed Sep 23 22:40:04 2020
    11 %% Update Count     : 24
     10%% Last Modified On : Wed Feb 17 09:21:15 2021
     11%% Update Count     : 27
    1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1313
     
    113113        morekeywords={
    114114                _Alignas, _Alignof, __alignof, __alignof__, asm, __asm, __asm__, __attribute, __attribute__,
    115                 auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__,
    116                 coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally,
     115                auto, basetypeof, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__,
     116                coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally, fixup,
    117117                __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__,
    118118                inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or,
    119                 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, suspend, thread,
    120                 _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__,
     119                otype, restrict, __restrict, __restrict__, recover, report, __signed, __signed__, _Static_assert, suspend,
     120                thread, _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__,
    121121                virtual, __volatile, __volatile__, waitfor, when, with, zero_t,
    122122    },
  • doc/theses/andrew_beach_MMath/existing.tex

    r2d019af r41ca6fa  
    1414\section{Overloading and \lstinline{extern}}
    1515\CFA has extensive overloading, allowing multiple definitions of the same name
    16 to be defined.~\cite{Moss18}
     16to be defined~\cite{Moss18}.
    1717\begin{cfa}
    1818char i; int i; double i;                        $\C[3.75in]{// variable overload}$
     
    4646pointers using the ampersand (@&@) instead of the pointer asterisk (@*@). \CFA
    4747references may also be mutable or non-mutable. If mutable, a reference variable
    48 may be assigned to using the address-of operator (@&@), which converts the
     48may be assigned using the address-of operator (@&@), which converts the
    4949reference to a pointer.
    5050\begin{cfa}
     
    5858\section{Constructors and Destructors}
    5959
    60 Both constructors and destructors are operators, which means they are just
     60Both constructors and destructors are operators, which means they are
    6161functions with special operator names rather than type names in \Cpp. The
    6262special operator names may be used to call the functions explicitly (not
     
    6464
    6565In general, operator names in \CFA are constructed by bracketing an operator
    66 token with @?@, which indicates where the arguments. For example, infixed
     66token with @?@, which indicates the position of the arguments. For example, infixed
    6767multiplication is @?*?@ while prefix dereference is @*?@. This syntax make it
    6868easy to tell the difference between prefix operations (such as @++?@) and
     
    8989definition, \CFA creates a default and copy constructor, destructor and
    9090assignment (like \Cpp). It is possible to define constructors/destructors for
    91 basic and existing types.
     91basic and existing types (unlike \Cpp).
    9292
    9393\section{Polymorphism}
     
    120120        do_once(value);
    121121}
    122 void do_once(int i) { ... }  // provide assertion
    123 int i;
     122void do_once(@int@ i) { ... }  // provide assertion
     123@int@ i;
    124124do_twice(i); // implicitly pass assertion do_once to do_twice
    125125\end{cfa}
     
    172172declarations instead of parameters, returns, and local variable declarations.
    173173\begin{cfa}
    174 forall(dtype T)
     174forall(dtype @T@)
    175175struct node {
    176         node(T) * next;  // generic linked node
    177         T * data;
    178 }
     176        node(@T@) * next;  // generic linked node
     177        @T@ * data;
     178}
     179node(@int@) inode;
    179180\end{cfa}
    180181The generic type @node(T)@ is an example of a polymorphic-type usage.  Like \Cpp
    181 templates usage, a polymorphic-type usage must specify a type parameter.
     182template usage, a polymorphic-type usage must specify a type parameter.
    182183
    183184There are many other polymorphism features in \CFA but these are the ones used
    184185by the exception system.
    185186
    186 \section{Concurrency}
    187 \CFA has a number of concurrency features: @thread@, @monitor@, @mutex@
    188 parameters, @coroutine@ and @generator@. The two features that interact with
    189 the exception system are @thread@ and @coroutine@; they and their supporting
     187\section{Control Flow}
     188\CFA has a number of advanced control-flow features: @generator@, @coroutine@, @monitor@, @mutex@ parameters, and @thread@.
     189The two features that interact with
     190the exception system are @coroutine@ and @thread@; they and their supporting
    190191constructs are described here.
    191192
     
    216217CountUp countup;
    217218\end{cfa}
    218 Each coroutine has @main@ function, which takes a reference to a coroutine
     219Each coroutine has a @main@ function, which takes a reference to a coroutine
    219220object and returns @void@.
    220221\begin{cfa}[numbers=left]
     
    230231In this function, or functions called by this function (helper functions), the
    231232@suspend@ statement is used to return execution to the coroutine's caller
    232 without terminating the coroutine.
     233without terminating the coroutine's function.
    233234
    234235A coroutine is resumed by calling the @resume@ function, \eg @resume(countup)@.
     
    242243@resume(countup).next@.
    243244
    244 \subsection{Monitors and Mutex}
     245\subsection{Monitor and Mutex Parameter}
    245246Concurrency does not guarantee ordering; without ordering results are
    246247non-deterministic. To claw back ordering, \CFA uses monitors and @mutex@
     
    260261and only one runs at a time.
    261262
    262 \subsection{Threads}
     263\subsection{Thread}
    263264Functions, generators, and coroutines are sequential so there is only a single
    264265(but potentially sophisticated) execution path in a program. Threads introduce
     
    268269monitors and mutex parameters. For threads to work safely with other threads,
    269270also requires mutual exclusion in the form of a communication rendezvous, which
    270 also supports internal synchronization as for mutex objects. For exceptions
    271 only the basic two basic operations are important: thread fork and join.
     271also supports internal synchronization as for mutex objects. For exceptions,
     272only two basic thread operations are important: fork and join.
    272273
    273274Threads are created like coroutines with an associated @main@ function:
  • doc/user/user.tex

    r2d019af r41ca6fa  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon Feb 15 13:48:53 2021
    14 %% Update Count     : 4452
     13%% Last Modified On : Sun Mar  7 21:50:24 2021
     14%% Update Count     : 4574
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    40764076
    40774077
     4078\subsection{Concurrent Stream Access}
     4079
     4080When a stream is shared by multiple threads, input or output characters can be intermixed or cause failure.
     4081For example, if two threads execute the following:
     4082\begin{cfa}
     4083$\emph{thread\(_1\)}$ : sout | "abc " | "def ";
     4084$\emph{thread\(_2\)}$ : sout | "uvw " | "xyz ";
     4085\end{cfa}
     4086possible outputs are:
     4087\begin{cquote}
     4088\begin{tabular}{@{}l|l|l|l|l@{}}
     4089\begin{cfa}
     4090abc def
     4091uvw xyz
     4092\end{cfa}
     4093&
     4094\begin{cfa}
     4095abc uvw xyz
     4096def
     4097\end{cfa}
     4098&
     4099\begin{cfa}
     4100uvw abc xyz def
     4101
     4102\end{cfa}
     4103&
     4104\begin{cfa}
     4105abuvwc dexf
     4106yz
     4107\end{cfa}
     4108&
     4109\begin{cfa}
     4110uvw abc def
     4111xyz
     4112\end{cfa}
     4113\end{tabular}
     4114\end{cquote}
     4115Concurrent operations can even corrupt the internal state of the stream resulting in failure.
     4116As a result, some form of mutual exclusion is required for concurrent stream access.
     4117
     4118A coarse-grained solution is to perform all stream operations via a single thread or within a monitor providing the necessary mutual exclusion for the stream.
     4119A fine-grained solution is to have a lock for each stream, which is acquired and released around stream operations by each thread.
     4120\CFA provides a fine-grained solution where a \Index{recursive lock} is acquired and released indirectly via a manipulator ©acquire© or instantiating an \Index{RAII} type specific for the kind of stream: ©osacquire©\index{ostream@©ostream©!osacquire@©osacquire©} for output streams and ©isacquire©\index{isacquire@©isacquire©}\index{istream@©istream©!isacquire@©isacquire©} for input streams.
     4121
     4122The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, where it should appear as the first item in a cascade list, \eg:
     4123\begin{cfa}
     4124$\emph{thread\(_1\)}$ : sout | @acquire@ | "abc " | "def ";   // manipulator
     4125$\emph{thread\(_2\)}$ : sout | @acquire@ | "uvw " | "xyz ";
     4126\end{cfa}
     4127Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order.
     4128\begin{cquote}
     4129\def\VRfont{\fontfamily{pcr}\upshape\selectfont}
     4130\begin{tabular}{@{}l|l@{}}
     4131\begin{cfa}
     4132abc def
     4133uvw xyz
     4134\end{cfa}
     4135&
     4136\begin{cfa}
     4137uvw xyz
     4138abc def
     4139\end{cfa}
     4140\end{tabular}
     4141\end{cquote}
     4142In summary, the stream lock is acquired by the ©acquire© manipulator and implicitly released at the end of the cascaded I/O expression ensuring all operations in the expression occur atomically.
     4143
     4144To lock a stream across multiple I/O operations, declare an instance of the appropriate ©osacquire© or ©isacquire© type to implicitly acquire and release the stream lock for the object's duration, \eg:
     4145\begin{cfa}
     4146{       // acquire sout for block duration
     4147        @osacquire@ acq = { sout };                             $\C{// named stream locker}$
     4148        sout | 1;
     4149        sout | @acquire@ | 2 | 3;                               $\C{// unnecessary, but ok to acquire and release again}$
     4150        sout | 4;
     4151}       // implicitly release the lock when "acq" is deallocated
     4152\end{cfa}
     4153Note, the unnecessary ©acquire© manipulator works because the recursive stream-lock can be acquired/released multiple times by the owner thread.
     4154Hence, calls to functions that also acquire a stream lock for their output do not result in \Index{deadlock}.
     4155
     4156The previous values written by threads 1 and 2 can be read in concurrently:
     4157\begin{cfa}
     4158{       // acquire sin lock for block duration
     4159        @isacquire acq = { sin };@                              $\C{// named stream locker}$
     4160        int x, y, z, w;
     4161        sin | x;
     4162        sin | @acquire@ | y | z;                                $\C{// unnecessary, but ok to acquire and release again}$
     4163        sin | w;
     4164}       // implicitly release the lock when "acq" is deallocated
     4165\end{cfa}
     4166Again, the order of the reading threads is non-deterministic.
     4167Note, non-deterministic reading is rare.
     4168
     4169\Textbf{WARNING:} The general problem of \Index{nested locking} can occur if routines are called in an I/O sequence that block, \eg:
     4170\begin{cfa}
     4171sout | @acquire@ | "data:" | rtn( mon );        $\C{// mutex call on monitor}$
     4172\end{cfa}
     4173If the thread executing the I/O expression blocks in the monitor with the ©sout© lock, other threads writing to ©sout© also block until the thread holding the lock is unblocked and releases it.
     4174This scenario can lead to \Index{deadlock}, if the thread that is going to unblock the thread waiting in the monitor first writes to ©sout© (deadly embrace).
     4175To prevent nested locking, a simple precaution is to factor out the blocking call from the expression, \eg:
     4176\begin{cfa}
     4177int @data@ = rtn( mon );
     4178sout | acquire | "data:" | @data@;
     4179\end{cfa}
     4180
     4181\Textbf{WARNING:} ©printf©\index{printf@©printf©}, ©scanf©\index{scanf@©scanf©} and their derivatives are unsafe when used with user-level threading, as in \CFA.
     4182These stream routines use kernel-thread locking (©futex©\index{futex@©futex©}), which block kernel threads, to prevent interleaving of I/O.
     4183However, the following simple example illustrates how a deadlock can occur (other complex scenarios are possible).
     4184Assume a single kernel thread and two user-level threads calling ©printf©.
     4185One user-level thread acquires the I/O lock and is time-sliced while performing ©printf©.
     4186The other user-level thread then starts execution, calls ©printf©, and blocks the only kernel thread because it cannot acquire the I/O lock.
     4187It does not help if the kernel lock is multiple acquisition, \ie, the lock owner can acquire it multiple times, because it then results in two user threads in the ©printf© critical section, corrupting the stream.
     4188
     4189
     4190\begin{comment}
    40784191\section{Types}
    40794192
     
    41544267process((int) s); // type is converted, no function is called
    41554268\end{cfa}
     4269\end{comment}
    41564270
    41574271
     
    43694483\begin{table}[hbt]
    43704484\centering
    4371 \input{../refrat/operidents}
     4485\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
     4486\begin{tabular}{@{}ll@{}}
     4487©?[?]©  & subscripting \impl{?[?]}                                      \\
     4488©?()©   & function call \impl{?()}                                      \\
     4489©?++©   & postfix increment \impl{?++}                          \\
     4490©?--©   & postfix decrement \impl{?--}                          \\
     4491©++?©   & prefix increment \impl{++?}                           \\
     4492©--?©   & prefix decrement \impl{--?}                           \\
     4493©*?©    & dereference \impl{*?}                                         \\
     4494©+?©    & unary plus \impl{+?}                                          \\
     4495©-?©    & arithmetic negation \impl{-?}                         \\
     4496©~?©    & bitwise negation \impl{~?}                            \\
     4497©!?©    & logical complement \impl{"!?}                         \\
     4498©?\?©   & exponentiation \impl{?\?}                                     \\
     4499©?*?©   & multiplication \impl{?*?}                                     \\
     4500©?/?©   & division \impl{?/?}                                           \\
     4501©?%?©   & remainder \impl{?%?}                                          \\
     4502\end{tabular}
     4503&
     4504\begin{tabular}{@{}ll@{}}
     4505©?+?©   & addition \impl{?+?}                                           \\
     4506©?-?©   & subtraction \impl{?-?}                                        \\
     4507©?<<?©  & left shift \impl{?<<?}                                        \\
     4508©?>>?©  & right shift \impl{?>>?}                                       \\
     4509©?<?©   & less than \impl{?<?}                                          \\
     4510©?<=?©  & less than or equal \impl{?<=?}                        \\
     4511©?>=?©  & greater than or equal \impl{?>=?}                     \\
     4512©?>?©   & greater than \impl{?>?}                                       \\
     4513©?==?©  & equality \impl{?==?}                                          \\
     4514©?!=?©  & inequality \impl{?"!=?}                                       \\
     4515©?&?©   & bitwise AND \impl{?&?}                                        \\
     4516©?^?©   & exclusive OR \impl{?^?}                                       \\
     4517©?|?©   & inclusive OR \impl{?"|?}                                      \\
     4518                                                                                                        \\
     4519                                                                                                        \\
     4520\end{tabular}
     4521&
     4522\begin{tabular}{@{}ll@{}}
     4523©?=?©   & simple assignment \impl{?=?}                          \\
     4524©?\=?©  & exponentiation assignment \impl{?\=?}         \\
     4525©?*=?©  & multiplication assignment \impl{?*=?}         \\
     4526©?/=?©  & division assignment \impl{?/=?}                       \\
     4527©?%=?©  & remainder assignment \impl{?%=?}                      \\
     4528©?+=?©  & addition assignment \impl{?+=?}                       \\
     4529©?-=?©  & subtraction assignment \impl{?-=?}            \\
     4530©?<<=?© & left-shift assignment \impl{?<<=?}            \\
     4531©?>>=?© & right-shift assignment \impl{?>>=?}           \\
     4532©?&=?©  & bitwise AND assignment \impl{?&=?}            \\
     4533©?^=?©  & exclusive OR assignment \impl{?^=?}           \\
     4534©?|=?©  & inclusive OR assignment \impl{?"|=?}          \\
     4535                                                                                                        \\
     4536                                                                                                        \\
     4537                                                                                                        \\
     4538\end{tabular}
     4539\end{tabular}
    43724540\caption{Operator Identifiers}
    43734541\label{opids}
     
    65026670\label{s:CFAKeywords}
    65036671
    6504 \CFA introduces the following new keywords.
     6672\CFA introduces the following new \Index{keyword}s, which cannot be used as identifiers.
    65056673
    65066674\begin{cquote}
    6507 \input{../refrat/keywords}
     6675\begin{tabular}{@{}lllllll@{}}
     6676\begin{tabular}{@{}l@{}}
     6677\Indexc{basetypeof}             \\
     6678\Indexc{choose}                 \\
     6679\Indexc{coroutine}              \\
     6680\Indexc{disable}                \\
     6681\end{tabular}
     6682&
     6683\begin{tabular}{@{}l@{}}
     6684\Indexc{enable}                 \\
     6685\Indexc{exception}              \\
     6686\Indexc{fallthrough}    \\
     6687\Indexc{fallthru}               \\
     6688\end{tabular}
     6689&
     6690\begin{tabular}{@{}l@{}}
     6691\Indexc{finally}                \\
     6692\Indexc{fixup}                  \\
     6693\Indexc{forall}                 \\
     6694\Indexc{generator}              \\
     6695\end{tabular}
     6696&
     6697\begin{tabular}{@{}l@{}}
     6698\Indexc{int128}                 \\
     6699\Indexc{monitor}                \\
     6700\Indexc{mutex}                  \\
     6701\Indexc{one_t}                  \\
     6702\end{tabular}
     6703&
     6704\begin{tabular}{@{}l@{}}
     6705\Indexc{report}                 \\
     6706\Indexc{suspend}                \\
     6707\Indexc{throw}                  \\
     6708\Indexc{throwResume}    \\
     6709\end{tabular}
     6710&
     6711\begin{tabular}{@{}l@{}}
     6712\Indexc{trait}                  \\
     6713\Indexc{try}                    \\
     6714\Indexc{virtual}                \\
     6715\Indexc{waitfor}                \\
     6716\end{tabular}
     6717&
     6718\begin{tabular}{@{}l@{}}
     6719\Indexc{when}                   \\
     6720\Indexc{with}                   \\
     6721\Indexc{zero_t}                 \\
     6722                                                \\
     6723\end{tabular}
     6724\end{tabular}
    65086725\end{cquote}
    6509 
     6726\CFA introduces the following new \Index{quasi-keyword}s, which can be used as identifiers.
     6727\begin{cquote}
     6728\begin{tabular}{@{}ll@{}}
     6729\begin{tabular}{@{}l@{}}
     6730\Indexc{catch}                  \\
     6731\Indexc{catchResume}    \\
     6732\Indexc{finally}                \\
     6733\end{tabular}
     6734&
     6735\begin{tabular}{@{}l@{}}
     6736\Indexc{fixup}                  \\
     6737\Indexc{or}                             \\
     6738\Indexc{timeout}                \\
     6739\end{tabular}
     6740\end{tabular}
     6741\end{cquote}
    65106742
    65116743\section{Standard Headers}
  • libcfa/src/bits/weakso_locks.hfa

    r2d019af r41ca6fa  
    6969static inline void  ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
    7070static inline void ^?{}( multiple_acquisition_lock & this ) {}
    71 static inline void   lock     ( multiple_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    72 static inline void   unlock   ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    73 static inline void   on_wait  ( multiple_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
     71static inline void   lock     ( multiple_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
     72static inline void   try_lock ( multiple_acquisition_lock & this ) { try_lock( (blocking_lock &)this ); }
     73static inline void   unlock   ( multiple_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
     74static inline void   on_wait  ( multiple_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); }
    7475static inline void   on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
    7576static inline void   set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
  • libcfa/src/concurrency/clib/cfathread.cfa

    r2d019af r41ca6fa  
    1414//
    1515
     16#include "fstream.hfa"
     17#include "locks.hfa"
    1618#include "kernel.hfa"
    1719#include "thread.hfa"
    18 
    19 thread CRunner {
    20         void (*themain)( CRunner * );
     20#include "time.hfa"
     21
     22#include "cfathread.h"
     23
     24struct cfathread_object {
     25        $thread self;
     26        void * (*themain)( void * );
     27        void * arg;
     28        void * ret;
    2129};
    22 
    23 static void ?{}( CRunner & this, void (*themain)( CRunner * ) ) {
     30void main(cfathread_object & this);
     31void ^?{}(cfathread_object & mutex this);
     32
     33static inline $thread * get_thread( cfathread_object & this ) { return &this.self; }
     34
     35typedef ThreadCancelled(cfathread_object) cfathread_exception;
     36typedef ThreadCancelled_vtable(cfathread_object) cfathread_vtable;
     37
     38void defaultResumptionHandler(ThreadCancelled(cfathread_object) & except) {
     39        abort | "A thread was cancelled";
     40}
     41
     42cfathread_vtable _cfathread_vtable_instance;
     43
     44cfathread_vtable const & get_exception_vtable(cfathread_exception *) {
     45        return _cfathread_vtable_instance;
     46}
     47
     48static void ?{}( cfathread_object & this, cluster & cl, void *(*themain)( void * ), void * arg ) {
    2449        this.themain = themain;
    25 }
    26 
    27 void main( CRunner & this ) {
    28         this.themain( &this );
     50        this.arg = arg;
     51        ((thread&)this){"C-thread", cl};
     52        __thrd_start(this, main);
     53}
     54
     55void ^?{}(cfathread_object & mutex this) {
     56        ^(this.self){};
     57}
     58
     59void main( cfathread_object & this ) {
     60        __attribute__((unused)) void * const thrd_obj = (void*)&this;
     61        __attribute__((unused)) void * const thrd_hdl = (void*)active_thread();
     62        /* paranoid */ verify( thrd_obj == thrd_hdl );
     63
     64        this.ret = this.themain( this.arg );
    2965}
    3066
     
    3369
    3470extern "C" {
    35         //--------------------
    36         // Basic thread management
    37         CRunner * cfathread_create( void (*main)( CRunner * ) ) {
    38                 return new( main );
    39         }
    40 
    41         void cfathread_join( CRunner * thrd ) {
     71        int cfathread_cluster_create(cfathread_cluster_t * cl) __attribute__((nonnull(1))) {
     72                *cl = new();
     73                return 0;
     74        }
     75
     76        cfathread_cluster_t cfathread_cluster_self(void) {
     77                return active_cluster();
     78        }
     79
     80        int cfathread_cluster_add_worker(cfathread_cluster_t cl, pthread_t* tid, void (*init_routine) (void *), void * arg) {
     81                // processor * proc = new("C-processor", *cl, init_routine, arg);
     82                processor * proc = alloc();
     83                (*proc){ "C-processor", *cl, init_routine, arg };
     84                if(tid) *tid = proc->kernel_thread;
     85                return 0;
     86        }
     87
     88        int cfathread_cluster_pause (cfathread_cluster_t) {
     89                abort | "Pausing clusters is not supported";
     90                exit(1);
     91        }
     92
     93        int cfathread_cluster_resume(cfathread_cluster_t) {
     94                abort | "Resuming clusters is not supported";
     95                exit(1);
     96        }
     97
     98        //--------------------
     99        // Thread attributes
     100        int cfathread_attr_init(cfathread_attr_t *attr) __attribute__((nonnull (1))) {
     101                attr->cl = active_cluster();
     102                return 0;
     103        }
     104
     105        //--------------------
     106        // Thread
     107        int cfathread_create( cfathread_t * handle, cfathread_attr_t * attr, void *(*main)( void * ), void * arg ) __attribute__((nonnull (1))) {
     108                cluster * cl = attr ? attr->cl : active_cluster();
     109                cfathread_t thrd = alloc();
     110                (*thrd){ *cl, main, arg };
     111                *handle = thrd;
     112                return 0;
     113        }
     114
     115        int cfathread_join( cfathread_t thrd, void ** retval ) {
     116                void * ret = join( *thrd ).ret;
    42117                delete( thrd );
     118                if(retval) {
     119                        *retval = ret;
     120                }
     121                return 0;
     122        }
     123
     124        cfathread_t cfathread_self(void) {
     125                return (cfathread_t)active_thread();
     126        }
     127
     128        int cfathread_usleep(useconds_t usecs) {
     129                sleep(usecs`us);
     130                return 0;
     131        }
     132
     133        int cfathread_sleep(unsigned int secs) {
     134                sleep(secs`s);
     135                return 0;
    43136        }
    44137
     
    47140        }
    48141
    49         void cfathread_unpark( CRunner * thrd ) {
     142        void cfathread_unpark( cfathread_t thrd ) {
    50143                unpark( *thrd );
    51144        }
     
    55148        }
    56149
    57         //--------------------
    58         // Basic kernel features
    59         void cfathread_setproccnt( int ncnt ) {
    60                 assert( ncnt >= 1 );
    61                 adelete( procs );
    62 
    63                 proc_cnt = ncnt - 1;
    64                 procs = anew(proc_cnt);
    65         }
    66 }
     150        typedef struct cfathread_mutex * cfathread_mutex_t;
     151
     152        //--------------------
     153        // Mutex
     154        struct cfathread_mutex {
     155                single_acquisition_lock impl;
     156        };
     157        int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; }
     158        int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1))) { delete( *mut ); return 0; }
     159        int cfathread_mutex_lock   (cfathread_mutex_t *mut) __attribute__((nonnull (1))) { lock    ( (*mut)->impl ); return 0; }
     160        int cfathread_mutex_trylock(cfathread_mutex_t *mut) __attribute__((nonnull (1))) { try_lock( (*mut)->impl ); return 0; }
     161        int cfathread_mutex_unlock (cfathread_mutex_t *mut) __attribute__((nonnull (1))) { unlock  ( (*mut)->impl ); return 0; }
     162
     163        //--------------------
     164        // Condition
     165        struct cfathread_condition {
     166                condition_variable(single_acquisition_lock) impl;
     167        };
     168        int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; }
     169        int cfathread_cond_signal(cfathread_cond_t *cond) __attribute__((nonnull (1)))  { notify_one( (*cond)->impl ); return 0; }
     170        int cfathread_cond_wait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut) __attribute__((nonnull (1,2))) { wait( (*cond)->impl, (*mut)->impl ); return 0; }
     171        int cfathread_cond_timedwait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut, const struct timespec *restrict abstime) __attribute__((nonnull (1,2,3))) {
     172                Time t = { *abstime };
     173                if( wait( (*cond)->impl, (*mut)->impl, t ) ) {
     174                        return 0;
     175                }
     176                errno = ETIMEDOUT;
     177                return ETIMEDOUT;
     178        }
     179}
     180
     181#include <iofwd.hfa>
     182
     183extern "C" {
     184        #include <unistd.h>
     185        #include <sys/types.h>
     186        #include <sys/socket.h>
     187
     188        //--------------------
     189        // IO operations
     190        int cfathread_socket(int domain, int type, int protocol) {
     191                return socket(domain, type, protocol);
     192        }
     193        int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len) {
     194                return bind(socket, address, address_len);
     195        }
     196
     197        int cfathread_listen(int socket, int backlog) {
     198                return listen(socket, backlog);
     199        }
     200
     201        int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) {
     202                return cfa_accept4(socket, address, address_len, 0, CFA_IO_LAZY);
     203        }
     204
     205        int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len) {
     206                return cfa_connect(socket, address, address_len, CFA_IO_LAZY);
     207        }
     208
     209        int cfathread_dup(int fildes) {
     210                return dup(fildes);
     211        }
     212
     213        int cfathread_close(int fildes) {
     214                return cfa_close(fildes, CFA_IO_LAZY);
     215        }
     216
     217        ssize_t cfathread_sendmsg(int socket, const struct msghdr *message, int flags) {
     218                return cfa_sendmsg(socket, message, flags, CFA_IO_LAZY);
     219        }
     220
     221        ssize_t cfathread_write(int fildes, const void *buf, size_t nbyte) {
     222                return cfa_write(fildes, buf, nbyte, CFA_IO_LAZY);
     223        }
     224
     225        ssize_t cfathread_recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len)  {
     226                struct iovec iov;
     227                iov.iov_base = buffer;
     228                iov.iov_len = length;
     229
     230                struct msghdr msg;
     231                msg.msg_name = address;
     232                msg.msg_namelen = address_len ? (socklen_t)*address_len : (socklen_t)0;
     233                msg.msg_iov = &iov;
     234                msg.msg_iovlen = 1;
     235                msg.msg_control = 0p;
     236                msg.msg_controllen = 0;
     237
     238                ssize_t ret = cfa_recvmsg(socket, &msg, flags, CFA_IO_LAZY);
     239
     240                if(address_len) *address_len = msg.msg_namelen;
     241                return ret;
     242        }
     243
     244        ssize_t cfathread_read(int fildes, void *buf, size_t nbyte) {
     245                return cfa_read(fildes, buf, nbyte, CFA_IO_LAZY);
     246        }
     247
     248        void cfathread_suspendFD(int) {
     249                abort | "Suspending File Descriptors is not supported";
     250        }
     251
     252        void cfathread_resumeFD (int) {
     253                abort | "Resuming File Descriptors is not supported";
     254        }
     255
     256}
  • libcfa/src/concurrency/clib/cfathread.h

    r2d019af r41ca6fa  
    2020extern "C" {
    2121#endif
     22        #include <asm/types.h>
     23        #include <errno.h>
     24        #include <unistd.h>
     25
     26
    2227        //--------------------
    2328        // Basic types
    24         struct cfathread_CRunner_t;
    25         typedef struct cfathread_CRunner_t * cfathread_t;
     29
     30        typedef struct cluster * cfathread_cluster_t;
     31
     32        int cfathread_cluster_create(cfathread_cluster_t * cluster) __attribute__((nonnull(1)));
     33        cfathread_cluster_t cfathread_cluster_self(void);
     34        int cfathread_cluster_add_worker(cfathread_cluster_t cluster, pthread_t* tid, void (*init_routine) (void *), void * arg);
     35        int cfathread_cluster_pause (cfathread_cluster_t cluster);
     36        int cfathread_cluster_resume(cfathread_cluster_t cluster);
    2637
    2738        //--------------------
    28         // Basic thread support
    29         cfathread_t cfathread_create( void (*main)( cfathread_t ) );
    30         void cfathread_join( cfathread_t );
     39        // thread attribute
     40        typedef struct cfathread_attr {
     41                cfathread_cluster_t cl;
     42        } cfathread_attr_t;
     43
     44        int cfathread_attr_init(cfathread_attr_t * attr) __attribute__((nonnull (1)));
     45        static inline int cfathread_attr_destroy(cfathread_attr_t * attr) __attribute__((nonnull (1))) { return 0; }
     46        static inline int cfathread_attr_setbackground(cfathread_attr_t * attr, int background) __attribute__((nonnull (1))) { return 0; }
     47        static inline int cfathread_attr_setcluster(cfathread_attr_t * attr, cfathread_cluster_t cl) __attribute__((nonnull (1))) { attr->cl = cl; return 0; }
     48
     49        //--------------------
     50        // thread type
     51        struct cfathread_object;
     52        typedef struct cfathread_object * cfathread_t;
     53
     54        int cfathread_create( cfathread_t * h, cfathread_attr_t * a, void *(*main)( void * ), void * arg ) __attribute__((nonnull (1)));
     55        int cfathread_join( cfathread_t, void ** retval );
     56
     57        int cfathread_get_errno(void);
     58        cfathread_t cfathread_self(void);
     59
     60        int cfathread_usleep(useconds_t usecs);
     61        int cfathread_sleep(unsigned int secs);
    3162
    3263        void cfathread_park( void );
     
    3566
    3667        //--------------------
    37         // Basic kernel features
    38         void cfathread_setproccnt( int );
     68        // mutex and condition
     69        struct timespec;
    3970
     71        typedef struct cfathread_mutex_attr {
     72        } cfathread_mutexattr_t;
     73        typedef struct cfathread_mutex * cfathread_mutex_t;
     74        int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict attr) __attribute__((nonnull (1)));
     75        int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
     76        int cfathread_mutex_lock(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
     77        int cfathread_mutex_trylock(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
     78        int cfathread_mutex_unlock(cfathread_mutex_t *mut) __attribute__((nonnull (1)));
     79
     80        typedef struct cfathread_cond_attr {
     81        } cfathread_condattr_t;
     82        typedef struct cfathread_condition * cfathread_cond_t;
     83        int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict attr) __attribute__((nonnull (1)));
     84        int cfathread_cond_wait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut) __attribute__((nonnull (1,2)));
     85        int cfathread_cond_timedwait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut, const struct timespec *restrict abstime) __attribute__((nonnull (1,2,3)));
     86        int cfathread_cond_signal(cfathread_cond_t *cond) __attribute__((nonnull (1)));
     87
     88        //--------------------
     89        // IO operations
     90        struct sockaddr;
     91        struct msghdr;
     92        int cfathread_socket(int domain, int type, int protocol);
     93        int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len);
     94        int cfathread_listen(int socket, int backlog);
     95        int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
     96        int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len);
     97        int cfathread_dup(int fildes);
     98        int cfathread_close(int fildes);
     99        ssize_t cfathread_sendmsg(int socket, const struct msghdr *message, int flags);
     100        ssize_t cfathread_write(int fildes, const void *buf, size_t nbyte);
     101        ssize_t cfathread_recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);
     102        ssize_t cfathread_read(int fildes, void *buf, size_t nbyte);
     103
     104        void cfathread_suspendFD(int fd);
     105        void cfathread_resumeFD (int fd);
    40106
    41107#if defined(__cforall) || defined(__cplusplus)
  • libcfa/src/concurrency/io/call.cfa.in

    r2d019af r41ca6fa  
    132132        extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    133133
    134         extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
     134        extern ssize_t splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags);
    135135        extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
    136136}
     
    366366        }),
    367367        # CFA_HAVE_IORING_OP_SPLICE
    368         Call('SPLICE', 'ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags)', {
     368        Call('SPLICE', 'ssize_t splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags)', {
    369369                'splice_fd_in': 'fd_in',
    370370                'splice_off_in': 'off_in ? (__u64)*off_in : (__u64)-1',
  • libcfa/src/concurrency/iofwd.hfa

    r2d019af r41ca6fa  
    5656struct epoll_event;
    5757
     58struct io_uring_sqe;
     59
    5860//----------
    5961// underlying calls
     
    9193extern ssize_t cfa_read(int fd, void * buf, size_t count, __u64 submit_flags);
    9294extern ssize_t cfa_write(int fd, void * buf, size_t count, __u64 submit_flags);
    93 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, __u64 submit_flags);
     95extern ssize_t cfa_splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags);
    9496extern ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags);
    9597
     
    124126void async_read(io_future_t & future, int fd, void * buf, size_t count, __u64 submit_flags);
    125127extern void async_write(io_future_t & future, int fd, void * buf, size_t count, __u64 submit_flags);
    126 extern 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, __u64 submit_flags);
     128extern void async_splice(io_future_t & future, int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags, __u64 submit_flags);
    127129extern void async_tee(io_future_t & future, int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags);
    128130
  • libcfa/src/concurrency/kernel.cfa

    r2d019af r41ca6fa  
    149149        #endif
    150150
     151        // if we need to run some special setup, now is the time to do it.
     152        if(this->init.fnc) {
     153                this->init.fnc(this->init.arg);
     154        }
     155
    151156        {
    152157                // Setup preemption data
  • libcfa/src/concurrency/kernel.hfa

    r2d019af r41ca6fa  
    107107        DLISTED_MGD_IMPL_IN(processor)
    108108
     109        // special init fields
     110        // This is needed for memcached integration
     111        // once memcached experiments are done this should probably be removed
     112        // it is not a particularly safe scheme as it can make processors less homogeneous
     113        struct {
     114                void (*fnc) (void *);
     115                void * arg;
     116        } init;
     117
    109118        #if !defined(__CFA_NO_STATISTICS__)
    110119                int print_stats;
     
    118127};
    119128
    120 void  ?{}(processor & this, const char name[], struct cluster & cltr);
     129void  ?{}(processor & this, const char name[], struct cluster & cltr, void (*init) (void *), void * arg);
    121130void ^?{}(processor & this);
    122131
    123 static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    124 static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    125 static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
     132static inline void  ?{}(processor & this)                        { this{ "Anonymous Processor", *mainCluster, 0p, 0p}; }
     133static inline void  ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr, 0p, 0p}; }
     134static inline void  ?{}(processor & this, const char name[])     { this{name, *mainCluster, 0p, 0p }; }
    126135
    127136DLISTED_MGD_IMPL_OUT(processor)
  • libcfa/src/concurrency/kernel/startup.cfa

    r2d019af r41ca6fa  
    7373static void __kernel_first_resume( processor * this );
    7474static void __kernel_last_resume ( processor * this );
    75 static void init(processor & this, const char name[], cluster & _cltr);
     75static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg);
    7676static void deinit(processor & this);
    7777static void doregister( struct cluster & cltr );
     
    198198                ( this.terminated ){};
    199199                ( this.runner ){};
    200                 init( this, "Main Processor", *mainCluster );
     200                init( this, "Main Processor", *mainCluster, 0p, 0p );
    201201                kernel_thread = pthread_self();
    202202
     
    452452}
    453453
    454 static void init(processor & this, const char name[], cluster & _cltr) with( this ) {
     454static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) with( this ) {
    455455        this.name = name;
    456456        this.cltr = &_cltr;
     
    464464        this.io.dirty   = false;
    465465
     466        this.init.fnc = fnc;
     467        this.init.arg = arg;
     468
    466469        this.idle = eventfd(0, 0);
    467470        if (idle < 0) {
     
    513516}
    514517
    515 void ?{}(processor & this, const char name[], cluster & _cltr) {
     518void ?{}(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) {
    516519        ( this.terminated ){};
    517520        ( this.runner ){};
    518521
    519522        disable_interrupts();
    520                 init( this, name, _cltr );
     523                init( this, name, _cltr, fnc, arg );
    521524        enable_interrupts( __cfaabi_dbg_ctx );
    522525
  • libcfa/src/concurrency/locks.hfa

    r2d019af r41ca6fa  
    3131static inline void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
    3232static inline void ^?{}( single_acquisition_lock & this ) {}
    33 static inline void   lock      ( single_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
    34 static inline void   unlock    ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
    35 static inline void   on_wait   ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
     33static inline void   lock      ( single_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
     34static inline void   try_lock  ( single_acquisition_lock & this ) { try_lock( (blocking_lock &)this ); }
     35static inline void   unlock    ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
     36static inline void   on_wait   ( single_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); }
    3637static inline void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    3738static inline void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
     
    4546static inline void  ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
    4647static inline void ^?{}( owner_lock & this ) {}
    47 static inline void   lock     ( owner_lock & this ) { lock   ( (blocking_lock &)this ); }
    48 static inline void   unlock   ( owner_lock & this ) { unlock ( (blocking_lock &)this ); }
    49 static inline void   on_wait  ( owner_lock & this ) { on_wait( (blocking_lock &)this ); }
     48static inline void   lock     ( owner_lock & this ) { lock    ( (blocking_lock &)this ); }
     49static inline void   try_lock ( owner_lock & this ) { try_lock( (blocking_lock &)this ); }
     50static inline void   unlock   ( owner_lock & this ) { unlock  ( (blocking_lock &)this ); }
     51static inline void   on_wait  ( owner_lock & this ) { on_wait ( (blocking_lock &)this ); }
    5052static inline void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
    5153static inline void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
  • libcfa/src/concurrency/monitor.hfa

    r2d019af r41ca6fa  
    6161static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } )
    6262void delete( T * th ) {
    63         ^(*th){};
     63        if(th) ^(*th){};
    6464        free( th );
    6565}
  • libcfa/src/concurrency/thread.hfa

    r2d019af r41ca6fa  
    4242forall(T &)
    4343const char * msg(ThreadCancelled(T) *);
    44 
    45 // define that satisfies the trait without using the thread keyword
    46 #define DECL_THREAD(X) $thread* get_thread(X& this) __attribute__((const)) { return &this.__thrd; } void main(X& this)
    4744
    4845// Inline getters for threads/coroutines/monitors
  • src/main.cc

    r2d019af r41ca6fa  
    99// Author           : Peter Buhr and Rob Schluntz
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Feb 19 14:59:00 2021
    13 // Update Count     : 643
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat Mar  6 15:49:00 2021
     13// Update Count     : 656
    1414//
    1515
     
    101101static string PreludeDirector = "";
    102102
    103 static void parse_cmdline( int argc, char *argv[] );
     103static void parse_cmdline( int argc, char * argv[] );
    104104static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false );
    105105static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
     
    159159#define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused ))
    160160
    161 static void Signal( int sig, void (*handler)(SIGPARMS), int flags ) {
     161static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) {
    162162        struct sigaction act;
    163163
     
    166166
    167167        if ( sigaction( sig, &act, nullptr ) == -1 ) {
    168             cerr << "*CFA runtime error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
     168            cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
    169169            _exit( EXIT_FAILURE );
    170170        } // if
     
    421421                        delete output;
    422422                } // if
    423         } catch ( SemanticErrorException &e ) {
     423        } catch ( SemanticErrorException & e ) {
    424424                if ( errorp ) {
    425425                        cerr << "---AST at error:---" << endl;
     
    432432                } // if
    433433                return EXIT_FAILURE;
    434         } catch ( UnimplementedError &e ) {
     434        } catch ( UnimplementedError & e ) {
    435435                cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
    436436                if ( output != &cout ) {
     
    438438                } // if
    439439                return EXIT_FAILURE;
    440         } catch ( CompilerError &e ) {
     440        } catch ( CompilerError & e ) {
    441441                cerr << "Compiler Error: " << e.get_what() << endl;
    442442                cerr << "(please report bugs to [REDACTED])" << endl;
     
    445445                } // if
    446446                return EXIT_FAILURE;
     447        } catch ( std::bad_alloc & ) {
     448                cerr << "*cfa-cpp compilation error* std::bad_alloc" << endl;
     449                backtrace( 1 );
     450                abort();
    447451        } catch ( ... ) {
    448452                exception_ptr eptr = current_exception();
     
    451455                                rethrow_exception(eptr);
    452456                        } else {
    453                                 cerr << "Exception Uncaught and Unknown" << endl;
    454                         } // if
    455                 } catch(const exception& e) {
    456                         cerr << "Uncaught Exception \"" << e.what() << "\"\n";
     457                                cerr << "*cfa-cpp compilation error* exception uncaught and unknown" << endl;
     458                        } // if
     459                } catch( const exception & e ) {
     460                        cerr << "*cfa-cpp compilation error* uncaught exception \"" << e.what() << "\"\n";
    457461                } // try
    458462                return EXIT_FAILURE;
     
    544548enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
    545549
    546 static void usage( char *argv[] ) {
     550static void usage( char * argv[] ) {
    547551    cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl;
    548552        int i = 0, j = 1;                                                                       // j skips starting colon
  • tests/concurrent/clib.c

    r2d019af r41ca6fa  
     1#include <stdio.h>
     2#include <stdlib.h>
    13#include <clib/cfathread.h>
    24
    3 #include <stdio.h>
    4 #include <stdlib.h>
     5extern "C" {
     6void _exit(int status);
     7}
    58
    69thread_local struct drand48_data buffer = { 0 };
     
    1518cfathread_t volatile blocked[blocked_size];
    1619
    17 void Worker( cfathread_t this ) {
     20void * Worker( void * ) {
    1821        for(int i = 0; i < 1000; i++) {
    1922                int idx = myrand() % blocked_size;
     
    2225                        cfathread_unpark( thrd );
    2326                } else {
    24                         cfathread_t thrd = __atomic_exchange_n(&blocked[idx], this, __ATOMIC_SEQ_CST);
     27                        cfathread_t thrd = __atomic_exchange_n(&blocked[idx], cfathread_self(), __ATOMIC_SEQ_CST);
    2528                        cfathread_unpark( thrd );
    2629                        cfathread_park();
     
    2831        }
    2932        printf("Done\n");
     33        return NULL;
    3034}
    3135
    3236volatile bool stop;
    33 void Unparker( cfathread_t this ) {
     37void * Unparker( void * ) {
    3438        while(!stop) {
    3539                int idx = myrand() % blocked_size;
     
    4246        }
    4347        printf("Done Unparker\n");
     48        return NULL;
    4449}
    4550
     
    5156        }
    5257
    53         cfathread_setproccnt( 4 );
    54         cfathread_t u = cfathread_create( Unparker );
     58        cfathread_cluster_t cl = cfathread_cluster_self();
     59
     60        cfathread_cluster_add_worker( cl, NULL, NULL, NULL );
     61        cfathread_cluster_add_worker( cl, NULL, NULL, NULL );
     62        cfathread_cluster_add_worker( cl, NULL, NULL, NULL );
     63        cfathread_t u;
     64        cfathread_create( &u, NULL, Unparker, NULL );
    5565        {
    5666                cfathread_t t[20];
    5767                for(int i = 0; i < 20; i++) {
    58                         t[i] = cfathread_create( Worker );
     68                        cfathread_create( &t[i], NULL, Worker, NULL );
    5969                }
    6070                for(int i = 0; i < 20; i++) {
    61                         cfathread_join( t[i] );
     71                        cfathread_join( t[i], NULL );
    6272                }
    6373        }
    6474        stop = true;
    65         cfathread_join(u);
    66         cfathread_setproccnt( 1 );
     75        cfathread_join(u, NULL);
     76        fflush(stdout);
     77        _exit(0);
    6778}
Note: See TracChangeset for help on using the changeset viewer.