Changeset e867b44
- Timestamp:
- Mar 13, 2021, 12:35:42 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 5f39135, b0d5c0c
- Parents:
- 2d019af (diff), df65c0c (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. - git-author:
- Peter A. Buhr <pabuhr@…> (03/12/21 23:14:36)
- git-committer:
- Peter A. Buhr <pabuhr@…> (03/13/21 12:35:42)
- Files:
-
- 4 added
- 18 edited
- 16 moved
Legend:
- Unmodified
- Added
- Removed
-
Jenkinsfile
r2d019af re867b44 148 148 def test() { 149 149 try { 150 // Print potential limits before testing 151 // in case jenkins messes with them 152 sh 'free -h' 153 sh 'ulimit -a' 154 150 155 Tools.BuildStage('Test: short', !Settings.RunAllTests) { 151 156 dir (BuildDir) { -
benchmark/Makefile.am
r2d019af re867b44 502 502 503 503 compile-io$(EXEEXT): 504 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io 1.cfa504 $(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io/io.cfa 505 505 506 506 compile-monitor$(EXEEXT): -
doc/LaTeXmacros/lstlang.sty
r2d019af re867b44 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Wed Sep 23 22:40:04 202011 %% Update Count : 2 410 %% Last Modified On : Wed Feb 17 09:21:15 2021 11 %% Update Count : 27 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 113 113 morekeywords={ 114 114 _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, 117 117 __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__, 118 118 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__, 121 121 virtual, __volatile, __volatile__, waitfor, when, with, zero_t, 122 122 }, -
doc/theses/andrew_beach_MMath/existing.tex
r2d019af re867b44 14 14 \section{Overloading and \lstinline{extern}} 15 15 \CFA has extensive overloading, allowing multiple definitions of the same name 16 to be defined .~\cite{Moss18}16 to be defined~\cite{Moss18}. 17 17 \begin{cfa} 18 18 char i; int i; double i; $\C[3.75in]{// variable overload}$ … … 46 46 pointers using the ampersand (@&@) instead of the pointer asterisk (@*@). \CFA 47 47 references may also be mutable or non-mutable. If mutable, a reference variable 48 may be assigned tousing the address-of operator (@&@), which converts the48 may be assigned using the address-of operator (@&@), which converts the 49 49 reference to a pointer. 50 50 \begin{cfa} … … 58 58 \section{Constructors and Destructors} 59 59 60 Both constructors and destructors are operators, which means they are just60 Both constructors and destructors are operators, which means they are 61 61 functions with special operator names rather than type names in \Cpp. The 62 62 special operator names may be used to call the functions explicitly (not … … 64 64 65 65 In general, operator names in \CFA are constructed by bracketing an operator 66 token with @?@, which indicates wherethe arguments. For example, infixed66 token with @?@, which indicates the position of the arguments. For example, infixed 67 67 multiplication is @?*?@ while prefix dereference is @*?@. This syntax make it 68 68 easy to tell the difference between prefix operations (such as @++?@) and … … 89 89 definition, \CFA creates a default and copy constructor, destructor and 90 90 assignment (like \Cpp). It is possible to define constructors/destructors for 91 basic and existing types .91 basic and existing types (unlike \Cpp). 92 92 93 93 \section{Polymorphism} … … 120 120 do_once(value); 121 121 } 122 void do_once( inti) { ... } // provide assertion123 inti;122 void do_once(@int@ i) { ... } // provide assertion 123 @int@ i; 124 124 do_twice(i); // implicitly pass assertion do_once to do_twice 125 125 \end{cfa} … … 172 172 declarations instead of parameters, returns, and local variable declarations. 173 173 \begin{cfa} 174 forall(dtype T)174 forall(dtype @T@) 175 175 struct node { 176 node(T) * next; // generic linked node 177 T * data; 178 } 176 node(@T@) * next; // generic linked node 177 @T@ * data; 178 } 179 node(@int@) inode; 179 180 \end{cfa} 180 181 The generic type @node(T)@ is an example of a polymorphic-type usage. Like \Cpp 181 template susage, a polymorphic-type usage must specify a type parameter.182 template usage, a polymorphic-type usage must specify a type parameter. 182 183 183 184 There are many other polymorphism features in \CFA but these are the ones used 184 185 by the exception system. 185 186 186 \section{Con currency}187 \CFA has a number of concurrency features: @thread@, @monitor@, @mutex@188 parameters, @coroutine@ and @generator@.The two features that interact with189 the exception system are @ thread@ and @coroutine@; they and their supporting187 \section{Control Flow} 188 \CFA has a number of advanced control-flow features: @generator@, @coroutine@, @monitor@, @mutex@ parameters, and @thread@. 189 The two features that interact with 190 the exception system are @coroutine@ and @thread@; they and their supporting 190 191 constructs are described here. 191 192 … … 216 217 CountUp countup; 217 218 \end{cfa} 218 Each coroutine has @main@ function, which takes a reference to a coroutine219 Each coroutine has a @main@ function, which takes a reference to a coroutine 219 220 object and returns @void@. 220 221 \begin{cfa}[numbers=left] … … 230 231 In this function, or functions called by this function (helper functions), the 231 232 @suspend@ statement is used to return execution to the coroutine's caller 232 without terminating the coroutine .233 without terminating the coroutine's function. 233 234 234 235 A coroutine is resumed by calling the @resume@ function, \eg @resume(countup)@. … … 242 243 @resume(countup).next@. 243 244 244 \subsection{Monitor s and Mutex}245 \subsection{Monitor and Mutex Parameter} 245 246 Concurrency does not guarantee ordering; without ordering results are 246 247 non-deterministic. To claw back ordering, \CFA uses monitors and @mutex@ … … 260 261 and only one runs at a time. 261 262 262 \subsection{Thread s}263 \subsection{Thread} 263 264 Functions, generators, and coroutines are sequential so there is only a single 264 265 (but potentially sophisticated) execution path in a program. Threads introduce … … 268 269 monitors and mutex parameters. For threads to work safely with other threads, 269 270 also requires mutual exclusion in the form of a communication rendezvous, which 270 also supports internal synchronization as for mutex objects. For exceptions 271 only t he basic two basic operations are important: threadfork and join.271 also supports internal synchronization as for mutex objects. For exceptions, 272 only two basic thread operations are important: fork and join. 272 273 273 274 Threads are created like coroutines with an associated @main@ function: -
doc/user/user.tex
r2d019af re867b44 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Feb 15 13:48:53202114 %% Update Count : 4 45213 %% Last Modified On : Sun Mar 7 21:50:24 2021 14 %% Update Count : 4574 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 4076 4076 4077 4077 4078 \subsection{Concurrent Stream Access} 4079 4080 When a stream is shared by multiple threads, input or output characters can be intermixed or cause failure. 4081 For 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} 4086 possible outputs are: 4087 \begin{cquote} 4088 \begin{tabular}{@{}l|l|l|l|l@{}} 4089 \begin{cfa} 4090 abc def 4091 uvw xyz 4092 \end{cfa} 4093 & 4094 \begin{cfa} 4095 abc uvw xyz 4096 def 4097 \end{cfa} 4098 & 4099 \begin{cfa} 4100 uvw abc xyz def 4101 4102 \end{cfa} 4103 & 4104 \begin{cfa} 4105 abuvwc dexf 4106 yz 4107 \end{cfa} 4108 & 4109 \begin{cfa} 4110 uvw abc def 4111 xyz 4112 \end{cfa} 4113 \end{tabular} 4114 \end{cquote} 4115 Concurrent operations can even corrupt the internal state of the stream resulting in failure. 4116 As a result, some form of mutual exclusion is required for concurrent stream access. 4117 4118 A 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. 4119 A 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 4122 The 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} 4127 Now, 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} 4132 abc def 4133 uvw xyz 4134 \end{cfa} 4135 & 4136 \begin{cfa} 4137 uvw xyz 4138 abc def 4139 \end{cfa} 4140 \end{tabular} 4141 \end{cquote} 4142 In 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 4144 To 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} 4153 Note, the unnecessary ©acquire© manipulator works because the recursive stream-lock can be acquired/released multiple times by the owner thread. 4154 Hence, calls to functions that also acquire a stream lock for their output do not result in \Index{deadlock}. 4155 4156 The 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} 4166 Again, the order of the reading threads is non-deterministic. 4167 Note, 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} 4171 sout | @acquire@ | "data:" | rtn( mon ); $\C{// mutex call on monitor}$ 4172 \end{cfa} 4173 If 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. 4174 This 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). 4175 To prevent nested locking, a simple precaution is to factor out the blocking call from the expression, \eg: 4176 \begin{cfa} 4177 int @data@ = rtn( mon ); 4178 sout | 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. 4182 These stream routines use kernel-thread locking (©futex©\index{futex@©futex©}), which block kernel threads, to prevent interleaving of I/O. 4183 However, the following simple example illustrates how a deadlock can occur (other complex scenarios are possible). 4184 Assume a single kernel thread and two user-level threads calling ©printf©. 4185 One user-level thread acquires the I/O lock and is time-sliced while performing ©printf©. 4186 The other user-level thread then starts execution, calls ©printf©, and blocks the only kernel thread because it cannot acquire the I/O lock. 4187 It 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} 4078 4191 \section{Types} 4079 4192 … … 4154 4267 process((int) s); // type is converted, no function is called 4155 4268 \end{cfa} 4269 \end{comment} 4156 4270 4157 4271 … … 4369 4483 \begin{table}[hbt] 4370 4484 \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} 4372 4540 \caption{Operator Identifiers} 4373 4541 \label{opids} … … 6502 6670 \label{s:CFAKeywords} 6503 6671 6504 \CFA introduces the following new keywords.6672 \CFA introduces the following new \Index{keyword}s, which cannot be used as identifiers. 6505 6673 6506 6674 \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} 6508 6725 \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} 6510 6742 6511 6743 \section{Standard Headers} -
libcfa/src/bits/weakso_locks.hfa
r2d019af re867b44 69 69 static inline void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };} 70 70 static 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 ); } 71 static inline void lock ( multiple_acquisition_lock & this ) { lock ( (blocking_lock &)this ); } 72 static inline void try_lock ( multiple_acquisition_lock & this ) { try_lock( (blocking_lock &)this ); } 73 static inline void unlock ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 74 static inline void on_wait ( multiple_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); } 74 75 static inline void on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); } 75 76 static 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 re867b44 14 14 // 15 15 16 #include "fstream.hfa" 17 #include "locks.hfa" 16 18 #include "kernel.hfa" 17 19 #include "thread.hfa" 18 19 thread CRunner { 20 void (*themain)( CRunner * ); 20 #include "time.hfa" 21 22 #include "cfathread.h" 23 24 struct cfathread_object { 25 $thread self; 26 void * (*themain)( void * ); 27 void * arg; 28 void * ret; 21 29 }; 22 23 static void ?{}( CRunner & this, void (*themain)( CRunner * ) ) { 30 void main(cfathread_object & this); 31 void ^?{}(cfathread_object & mutex this); 32 33 static inline $thread * get_thread( cfathread_object & this ) { return &this.self; } 34 35 typedef ThreadCancelled(cfathread_object) cfathread_exception; 36 typedef ThreadCancelled_vtable(cfathread_object) cfathread_vtable; 37 38 void defaultResumptionHandler(ThreadCancelled(cfathread_object) & except) { 39 abort | "A thread was cancelled"; 40 } 41 42 cfathread_vtable _cfathread_vtable_instance; 43 44 cfathread_vtable const & get_exception_vtable(cfathread_exception *) { 45 return _cfathread_vtable_instance; 46 } 47 48 static void ?{}( cfathread_object & this, cluster & cl, void *(*themain)( void * ), void * arg ) { 24 49 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 55 void ^?{}(cfathread_object & mutex this) { 56 ^(this.self){}; 57 } 58 59 void 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 ); 29 65 } 30 66 … … 33 69 34 70 extern "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; 42 117 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; 43 136 } 44 137 … … 47 140 } 48 141 49 void cfathread_unpark( CRunner *thrd ) {142 void cfathread_unpark( cfathread_t thrd ) { 50 143 unpark( *thrd ); 51 144 } … … 55 148 } 56 149 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 183 extern "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 re867b44 20 20 extern "C" { 21 21 #endif 22 #include <asm/types.h> 23 #include <errno.h> 24 #include <unistd.h> 25 26 22 27 //-------------------- 23 28 // 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); 26 37 27 38 //-------------------- 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); 31 62 32 63 void cfathread_park( void ); … … 35 66 36 67 //-------------------- 37 // Basic kernel features38 void cfathread_setproccnt( int );68 // mutex and condition 69 struct timespec; 39 70 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); 40 106 41 107 #if defined(__cforall) || defined(__cplusplus) -
libcfa/src/concurrency/io/call.cfa.in
r2d019af re867b44 132 132 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 133 133 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); 135 135 extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags); 136 136 } … … 366 366 }), 367 367 # 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)', { 369 369 'splice_fd_in': 'fd_in', 370 370 'splice_off_in': 'off_in ? (__u64)*off_in : (__u64)-1', -
libcfa/src/concurrency/iofwd.hfa
r2d019af re867b44 56 56 struct epoll_event; 57 57 58 struct io_uring_sqe; 59 58 60 //---------- 59 61 // underlying calls … … 91 93 extern ssize_t cfa_read(int fd, void * buf, size_t count, __u64 submit_flags); 92 94 extern 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);95 extern 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); 94 96 extern ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags); 95 97 … … 124 126 void async_read(io_future_t & future, int fd, void * buf, size_t count, __u64 submit_flags); 125 127 extern 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);128 extern 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); 127 129 extern void async_tee(io_future_t & future, int fd_in, int fd_out, size_t len, unsigned int flags, __u64 submit_flags); 128 130 -
libcfa/src/concurrency/kernel.cfa
r2d019af re867b44 149 149 #endif 150 150 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 151 156 { 152 157 // Setup preemption data -
libcfa/src/concurrency/kernel.hfa
r2d019af re867b44 107 107 DLISTED_MGD_IMPL_IN(processor) 108 108 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 109 118 #if !defined(__CFA_NO_STATISTICS__) 110 119 int print_stats; … … 118 127 }; 119 128 120 void ?{}(processor & this, const char name[], struct cluster & cltr );129 void ?{}(processor & this, const char name[], struct cluster & cltr, void (*init) (void *), void * arg); 121 130 void ^?{}(processor & this); 122 131 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}; }132 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster, 0p, 0p}; } 133 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr, 0p, 0p}; } 134 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster, 0p, 0p }; } 126 135 127 136 DLISTED_MGD_IMPL_OUT(processor) -
libcfa/src/concurrency/kernel/startup.cfa
r2d019af re867b44 73 73 static void __kernel_first_resume( processor * this ); 74 74 static void __kernel_last_resume ( processor * this ); 75 static void init(processor & this, const char name[], cluster & _cltr );75 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg); 76 76 static void deinit(processor & this); 77 77 static void doregister( struct cluster & cltr ); … … 198 198 ( this.terminated ){}; 199 199 ( this.runner ){}; 200 init( this, "Main Processor", *mainCluster );200 init( this, "Main Processor", *mainCluster, 0p, 0p ); 201 201 kernel_thread = pthread_self(); 202 202 … … 452 452 } 453 453 454 static void init(processor & this, const char name[], cluster & _cltr ) with( this ) {454 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) with( this ) { 455 455 this.name = name; 456 456 this.cltr = &_cltr; … … 464 464 this.io.dirty = false; 465 465 466 this.init.fnc = fnc; 467 this.init.arg = arg; 468 466 469 this.idle = eventfd(0, 0); 467 470 if (idle < 0) { … … 513 516 } 514 517 515 void ?{}(processor & this, const char name[], cluster & _cltr ) {518 void ?{}(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) { 516 519 ( this.terminated ){}; 517 520 ( this.runner ){}; 518 521 519 522 disable_interrupts(); 520 init( this, name, _cltr );523 init( this, name, _cltr, fnc, arg ); 521 524 enable_interrupts( __cfaabi_dbg_ctx ); 522 525 -
libcfa/src/concurrency/locks.hfa
r2d019af re867b44 31 31 static inline void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} 32 32 static 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 ); } 33 static inline void lock ( single_acquisition_lock & this ) { lock ( (blocking_lock &)this ); } 34 static inline void try_lock ( single_acquisition_lock & this ) { try_lock( (blocking_lock &)this ); } 35 static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 36 static inline void on_wait ( single_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); } 36 37 static inline void on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } 37 38 static inline void set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); } … … 45 46 static inline void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };} 46 47 static 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 ); } 48 static inline void lock ( owner_lock & this ) { lock ( (blocking_lock &)this ); } 49 static inline void try_lock ( owner_lock & this ) { try_lock( (blocking_lock &)this ); } 50 static inline void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); } 51 static inline void on_wait ( owner_lock & this ) { on_wait ( (blocking_lock &)this ); } 50 52 static inline void on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } 51 53 static inline void set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); } -
libcfa/src/concurrency/monitor.hfa
r2d019af re867b44 61 61 static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } ) 62 62 void delete( T * th ) { 63 ^(*th){};63 if(th) ^(*th){}; 64 64 free( th ); 65 65 } -
libcfa/src/concurrency/thread.hfa
r2d019af re867b44 42 42 forall(T &) 43 43 const char * msg(ThreadCancelled(T) *); 44 45 // define that satisfies the trait without using the thread keyword46 #define DECL_THREAD(X) $thread* get_thread(X& this) __attribute__((const)) { return &this.__thrd; } void main(X& this)47 44 48 45 // Inline getters for threads/coroutines/monitors -
src/main.cc
r2d019af re867b44 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Feb 19 14:59:00 202113 // Update Count : 6 4311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Mar 6 15:49:00 2021 13 // Update Count : 656 14 14 // 15 15 … … 101 101 static string PreludeDirector = ""; 102 102 103 static void parse_cmdline( int argc, char * argv[] );103 static void parse_cmdline( int argc, char * argv[] ); 104 104 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 105 105 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); … … 159 159 #define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused )) 160 160 161 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) {161 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) { 162 162 struct sigaction act; 163 163 … … 166 166 167 167 if ( sigaction( sig, &act, nullptr ) == -1 ) { 168 cerr << "* CFA runtimeerror* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;168 cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl; 169 169 _exit( EXIT_FAILURE ); 170 170 } // if … … 421 421 delete output; 422 422 } // if 423 } catch ( SemanticErrorException & e ) {423 } catch ( SemanticErrorException & e ) { 424 424 if ( errorp ) { 425 425 cerr << "---AST at error:---" << endl; … … 432 432 } // if 433 433 return EXIT_FAILURE; 434 } catch ( UnimplementedError & e ) {434 } catch ( UnimplementedError & e ) { 435 435 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; 436 436 if ( output != &cout ) { … … 438 438 } // if 439 439 return EXIT_FAILURE; 440 } catch ( CompilerError & e ) {440 } catch ( CompilerError & e ) { 441 441 cerr << "Compiler Error: " << e.get_what() << endl; 442 442 cerr << "(please report bugs to [REDACTED])" << endl; … … 445 445 } // if 446 446 return EXIT_FAILURE; 447 } catch ( std::bad_alloc & ) { 448 cerr << "*cfa-cpp compilation error* std::bad_alloc" << endl; 449 backtrace( 1 ); 450 abort(); 447 451 } catch ( ... ) { 448 452 exception_ptr eptr = current_exception(); … … 451 455 rethrow_exception(eptr); 452 456 } 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"; 457 461 } // try 458 462 return EXIT_FAILURE; … … 544 548 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) }; 545 549 546 static void usage( char * argv[] ) {550 static void usage( char * argv[] ) { 547 551 cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl; 548 552 int i = 0, j = 1; // j skips starting colon -
tests/concurrent/clib.c
r2d019af re867b44 1 #include <stdio.h> 2 #include <stdlib.h> 1 3 #include <clib/cfathread.h> 2 4 3 #include <stdio.h> 4 #include <stdlib.h> 5 extern "C" { 6 void _exit(int status); 7 } 5 8 6 9 thread_local struct drand48_data buffer = { 0 }; … … 15 18 cfathread_t volatile blocked[blocked_size]; 16 19 17 void Worker( cfathread_t this) {20 void * Worker( void * ) { 18 21 for(int i = 0; i < 1000; i++) { 19 22 int idx = myrand() % blocked_size; … … 22 25 cfathread_unpark( thrd ); 23 26 } 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); 25 28 cfathread_unpark( thrd ); 26 29 cfathread_park(); … … 28 31 } 29 32 printf("Done\n"); 33 return NULL; 30 34 } 31 35 32 36 volatile bool stop; 33 void Unparker( cfathread_t this) {37 void * Unparker( void * ) { 34 38 while(!stop) { 35 39 int idx = myrand() % blocked_size; … … 42 46 } 43 47 printf("Done Unparker\n"); 48 return NULL; 44 49 } 45 50 … … 51 56 } 52 57 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 ); 55 65 { 56 66 cfathread_t t[20]; 57 67 for(int i = 0; i < 20; i++) { 58 t[i] = cfathread_create( Worker);68 cfathread_create( &t[i], NULL, Worker, NULL ); 59 69 } 60 70 for(int i = 0; i < 20; i++) { 61 cfathread_join( t[i] );71 cfathread_join( t[i], NULL ); 62 72 } 63 73 } 64 74 stop = true; 65 cfathread_join(u); 66 cfathread_setproccnt( 1 ); 75 cfathread_join(u, NULL); 76 fflush(stdout); 77 _exit(0); 67 78 }
Note: See TracChangeset
for help on using the changeset viewer.