Changes in / [a6c45c6:2d8a770]
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
ra6c45c6 r2d8a770 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Feb 14 15:52:46202114 %% Update Count : 5 2413 %% Last Modified On : Tue Apr 27 12:03:17 2021 14 %% Update Count : 539 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 102 102 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 103 103 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 104 \renewcommand\subparagraph{\@startsection{subparagraph}{4}{\z@}{-1.5ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries\itshape}} 104 105 105 106 % index macros … … 284 285 showlines=true, % show blank lines at end of code 285 286 aboveskip=4pt, % spacing above/below code block 286 belowskip= 0pt,287 belowskip=2pt, 287 288 numberstyle=\footnotesize\sf, % numbering style 288 289 % replace/adjust listing characters that look bad in sanserif … … 297 298 \lstset{ 298 299 language=CFA, 299 moredelim=**[is][\color{red}]{@}{@}, % red highlighting @...@300 %moredelim=**[is][\color{red}]{®}{®}, % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.300 %moredelim=**[is][\color{red}]{@}{@}, % red highlighting @...@ 301 moredelim=**[is][\color{red}]{®}{®}, % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 301 302 %moredelim=**[is][\color{blue}]{ß}{ß}, % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 302 303 %moredelim=**[is][\color{OliveGreen}]{¢}{¢}, % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" -
doc/user/user.tex
ra6c45c6 r2d8a770 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Apr 25 19:03:03202114 %% Update Count : 495113 %% Last Modified On : Wed Apr 28 21:48:59 2021 14 %% Update Count : 5051 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 3312 3312 3313 3313 \section{Tuples} 3314 \label{tuples} 3314 3315 3315 3316 In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call. … … 3420 3421 3421 3422 \subsection{Tuple Coercions} 3423 \label{tuple coercions}\label{coercions!tuple} 3422 3424 3423 3425 There are four coercions that can be performed on tuples and tuple variables: closing, opening, flattening and structuring. … … 3464 3466 3465 3467 \subsection{Mass Assignment} 3468 \label{mass assignment}\label{assignment!mass} 3466 3469 3467 3470 \CFA permits assignment to several variables at once using mass assignment~\cite{CLU}. … … 3504 3507 3505 3508 \subsection{Multiple Assignment} 3509 \label{multiple assignment}\label{assignment!multiple} 3506 3510 3507 3511 \CFA also supports the assignment of several values at once, known as multiple assignment~\cite{CLU,Galletly96}. … … 3545 3549 3546 3550 \subsection{Cascade Assignment} 3551 \index{cascade assignment}\index{assignment!cascade} 3547 3552 3548 3553 As in C, \CFA mass and multiple assignments can be cascaded, producing cascade assignment. … … 3564 3569 \section{Stream I/O Library} 3565 3570 \label{s:StreamIOLibrary} 3566 \index{input /output stream library}3567 \index{stream library} 3571 \index{input}\index{output} 3572 \index{stream library}\index{library!stream} 3568 3573 3569 3574 The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 3570 3575 Stream I/O can be implicitly or explicitly formatted. 3571 Implicit formatting means \CFA selects the output or input format for values that match with the type of a variable.3576 Implicit formatting means \CFA selects the output or input format for values that matches the variable's type. 3572 3577 Explicit formatting means additional information is specified to augment how an output or input of value is interpreted. 3573 \CFA formatting i s a cross between C ©printf© and \CC ©cout© manipulators, and Python implicit spacing and newline.3578 \CFA formatting incorporates ideas from C ©printf©, \CC ©stream© manipulators, and Python implicit spacing and newline. 3574 3579 Specifically: 3575 3580 \begin{itemize} … … 3584 3589 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 3585 3590 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 3586 (To guarantee no side-effects, manipulator values must be saved and restored across function calls.) 3587 \item 3588 \CFA has more sophisticated implicit spacing between valuesthan Python, plus implicit newline at the end of a print.3591 Furthermore, to guarantee no side-effects, manipulator values must be saved and restored across function calls. 3592 \item 3593 \CFA has more sophisticated implicit value spacing than Python, plus implicit newline at the end of a print. 3589 3594 \end{itemize} 3595 3596 The standard polymorphic I/Os stream are ©stdin©/©sin© (input), ©stdout©/©sout© and ©stderr©/©serr© (output) (like C++ ©cin©/©cout©/©cerr©). 3597 Polymorphic streams ©exit© and ©abort© provide implicit program termination without and with generating a stack trace and core file. 3598 Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell. 3599 \begin{cfa} 3600 ®exit® | "x (" | x | ") negative value."; // terminate and return EXIT_FAILURE to shell 3601 ®abort® | "x (" | x | ") negative value."; // terminate and generate stack trace and core file 3602 \end{cfa} 3603 Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively. 3590 3604 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 3605 3606 3607 \subsection{Basic I/O} 3591 3608 3592 3609 For implicit formatted output, the common case is printing a series of variables separated by whitespace. … … 3601 3618 \begin{cfa} 3602 3619 3603 cout << x ®<< " "® << y ®<< " "® << z<< endl;3620 cout << x ®<< " "® << y ®<< " "® << z << endl; 3604 3621 \end{cfa} 3605 3622 & … … 3653 3670 \end{tabular} 3654 3671 \end{cquote} 3655 Input and output use a uniform operator, ©|©, rather than separate operators, as in ©>>© and ©<<© for \CC.3672 Input and output use a uniform operator, ©|©, rather than \CC's ©>>© and ©<<© input/output operators. 3656 3673 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output. 3657 3674 … … 3698 3715 \end{cquote} 3699 3716 3717 \VRef[Figure]{f:CFACommand-LineProcessing} shows idiomatic \CFA command-line processing and copying an input file to an output file. 3718 Note, a stream variable may be copied because it is a reference to an underlying stream data-structures. 3719 All I/O errors are handles as exceptions, but end-of-file is not an exception as C programmers are use to explicitly checking for it. 3720 3721 \begin{figure} 3722 \begin{cfa} 3723 #include ®<fstream.hfa>® 3724 3725 int main( int argc, char * argv[] ) { 3726 ®ifstream® in = stdin; $\C{// copy default files}$ 3727 ®ofstream® out = stdout; 3728 3729 try { 3730 choose ( argc ) { 3731 case 2, 3: 3732 ®open®( in, argv[1] ); $\C{// open input file first as output creates file}$ 3733 if ( argc == 3 ) ®open®( out, argv[2] ); $\C{// do not create output unless input opens}$ 3734 case 1: ; $\C{// use default files}$ 3735 default: 3736 ®exit® | "Usage" | argv[0] | "[ input-file (default stdin) " 3737 "[ output-file (default stdout) ] ]"; 3738 } // choose 3739 } catch( ®Open_Failure® * ex; ex->istream == &in ) { 3740 ®exit® | "Unable to open input file" | argv[1]; 3741 } catch( ®Open_Failure® * ex; ex->ostream == &out ) { 3742 ®close®( in ); $\C{// optional}$ 3743 ®exit® | "Unable to open output file" | argv[2]; 3744 } // try 3745 3746 out | nlOff; $\C{// turn off auto newline}$ 3747 in | nlOn; $\C{// turn on reading newline}$ 3748 char ch; 3749 for () { $\C{// read/write characters}$ 3750 in | ch; 3751 if ( eof( in ) ) break; $\C{// eof ?}$ 3752 out | ch; 3753 } // for 3754 } // main 3755 \end{cfa} 3756 \caption{\CFA Command-Line Processing} 3757 \label{f:CFACommand-LineProcessing} 3758 \end{figure} 3759 3760 \VRef[Figure]{f:StreamFunctions} shows the stream operations. 3761 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 3762 \item 3763 \Indexc{fail} tests the stream error-indicator, returning nonzero if it is set. 3764 \item 3765 \Indexc{clear} resets the stream error-indicator. 3766 \item 3767 \Indexc{flush} (©ofstream© only) causes any unwritten data for a stream to be written to the file. 3768 \item 3769 \Indexc{eof} (©ifstream© only) tests the end-of-file indicator for the stream pointed to by stream. 3770 Returns true if the end-of-file indicator is set, otherwise false. 3771 \item 3772 \Indexc{open} binds the file with ©name© to a stream accessed with ©mode© (see ©fopen©). 3773 \item 3774 \Indexc{close} flushes the stream and closes the file. 3775 \item 3776 \Indexc{write} (©ofstream© only) write ©size© bytes to the stream. 3777 The bytes are written lazily to file when internal buffers fill. 3778 Eager buffer writes are done with ©flush© 3779 \item 3780 \Indexc{read} (©ifstream© only) read ©size© bytes to the stream. 3781 \item 3782 \Indexc{ungetc} (©ifstream© only) pushes the character back to the input stream. 3783 Pushed-back characters returned by subsequent reads in the reverse order of pushing. 3784 \end{itemize} 3785 The constructor functions: 3786 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 3787 \item 3788 create an unbound stream, which is subsequently bound to a file with ©open©. 3789 \item 3790 create a bound stream to the associated file with given ©mode©. 3791 \end{itemize} 3792 The destructor closes the stream. 3793 3794 \begin{figure} 3795 \begin{cfa} 3796 // *********************************** ofstream *********************************** 3797 3798 bool fail( ofstream & );$\indexc{fail}\index{ofstream@©ofstream©!©fail©}$ 3799 void clear( ofstream & );$\indexc{clear}\index{ofstream@©ofstream©!©clear©}$ 3800 int flush( ofstream & );$\indexc{flush}\index{ofstream@©ofstream©!©flush©}$ 3801 void open( ofstream &, const char name[], const char mode[] = "w" );$\indexc{open}\index{ofstream@©ofstream©!©open©}$ 3802 void close( ofstream & );$\indexc{close}\index{ofstream@©ofstream©!©close©}$ 3803 ofstream & write( ofstream &, const char data[], size_t size );$\indexc{write}\index{ofstream@©ofstream©!©write©}$ 3804 3805 void ?{}( ofstream & );$\index{ofstream@©ofstream©!©?{}©}$ 3806 void ?{}( ofstream &, const char name[], const char mode[] = "w" ); 3807 void ^?{}( ofstream & );$\index{ofstream@©ofstream©!©^?{}©}$ 3808 3809 // *********************************** ifstream *********************************** 3810 3811 bool fail( ifstream & is );$\indexc{fail}\index{ifstream@©ifstream©!©fail©}$ 3812 void clear( ifstream & );$\indexc{clear}\index{ifstream@©ifstream©!©clear©}$ 3813 bool eof( ifstream & is );$\indexc{eof}\index{ifstream@©ifstream©!©eof©}$ 3814 void open( ifstream & is, const char name[], const char mode[] = "r" );$\indexc{open}\index{ifstream@©ifstream©!©open©}$ 3815 void close( ifstream & is );$\indexc{close}\index{ifstream@©ifstream©!©close©}$ 3816 ifstream & read( ifstream & is, char data[], size_t size );$\indexc{read}\index{ifstream@©ifstream©!©read©}$ 3817 ifstream & ungetc( ifstream & is, char c );$\indexc{unget}\index{ifstream@©ifstream©!©unget©}$ 3818 3819 void ?{}( ifstream & is );$\index{ifstream@©ifstream©!©?{}©}$ 3820 void ?{}( ifstream & is, const char name[], const char mode[] = "r" ); 3821 void ^?{}( ifstream & is );$\index{ifstream@©ifstream©!©^?{}©}$ 3822 \end{cfa} 3823 \caption{Stream Functions} 3824 \label{f:StreamFunctions} 3825 \end{figure} 3700 3826 3701 3827 … … 4030 4156 sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" ); 4031 4157 \end{cfa} 4032 \begin{cfa}[showspaces=true,aboveskip=0pt ,belowskip=0pt]4158 \begin{cfa}[showspaces=true,aboveskip=0pt] 4033 4159 ® ®34 ® ®34 34 4034 4160 ® ®4.000000 ® ®4.000000 4.000000 … … 4378 4504 \end{cfa} 4379 4505 4380 \Textbf{WARNING:} ©printf©\index{printf@©printf©}, ©scanf©\index{scanf@©scanf©} and their derivatives are unsafe when used with user-level threading, as in \CFA. 4381 These stream routines use kernel-thread locking (©futex©\index{futex@©futex©}), which block kernel threads, to prevent interleaving of I/O. 4382 However, the following simple example illustrates how a deadlock can occur (other complex scenarios are possible). 4383 Assume a single kernel thread and two user-level threads calling ©printf©. 4384 One user-level thread acquires the I/O lock and is time-sliced while performing ©printf©. 4385 The other user-level thread then starts execution, calls ©printf©, and blocks the only kernel thread because it cannot acquire the I/O lock. 4386 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. 4506 4507 \section{String Stream} 4508 4509 All the stream formatting capabilities are available to format text to/from a C string rather than to a stream file. 4510 \VRef[Figure]{f:StringStreamProcessing} shows writing (output) and reading (input) from a C string. 4511 \begin{figure} 4512 \begin{cfa} 4513 #include <fstream.hfa> 4514 #include <strstream.hfa> 4515 4516 int main() { 4517 enum { size = 256 }; 4518 char buf[size]; $\C{// output buffer}$ 4519 ®ostrstream osstr = { buf, size };® $\C{// bind output buffer/size}$ 4520 int i = 3, j = 5, k = 7; 4521 double x = 12345678.9, y = 98765.4321e-11; 4522 4523 osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); $\C{// same lines of output}$ 4524 write( osstr ); 4525 printf( "%s", buf ); 4526 sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); 4527 4528 char buf2[] = "12 14 15 3.5 7e4"; $\C{// input buffer}$ 4529 ®istrstream isstr = { buf2 };® 4530 isstr | i | j | k | x | y; 4531 sout | i | j | k | x | y; 4532 } 4533 \end{cfa} 4534 \caption{String Stream Processing} 4535 \label{f:StringStreamProcessing} 4536 \end{figure} 4537 4538 \VRef[Figure]{f:StringStreamFunctions} shows the string stream operations. 4539 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4540 \item 4541 \Indexc{write} (©ostrstream© only) writes all the buffered characters to the specified stream (©stdout© default). 4542 \end{itemize} 4543 The constructor functions: 4544 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4545 \item 4546 create a bound stream to a write buffer (©ostrstream©) of ©size© or a read buffer (©istrstream©) containing a C string terminated with ©'\0'©. 4547 \end{itemize} 4548 4549 \begin{figure} 4550 \begin{cfa} 4551 // *********************************** ostrstream *********************************** 4552 4553 ostrstream & write( ostrstream & os, FILE * stream = stdout ); 4554 4555 void ?{}( ostrstream &, char buf[], size_t size ); 4556 4557 // *********************************** istrstream *********************************** 4558 4559 void ?{}( istrstream & is, char buf[] ); 4560 \end{cfa} 4561 \caption{String Stream Functions} 4562 \label{f:StringStreamFunctions} 4563 \end{figure} 4387 4564 4388 4565 … … 8111 8288 \begin{cquote} 8112 8289 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 8113 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c }{\textbf{C}@{}} \\8290 \multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{C}} \\ 8114 8291 \hline 8115 8292 \begin{cfa} 8116 #include <gmp >$\indexc{gmp}$8293 #include <gmp.hfa>$\indexc{gmp}$ 8117 8294 int main( void ) { 8118 8295 sout | "Factorial Numbers"; -
libcfa/src/concurrency/clib/cfathread.cfa
ra6c45c6 r2d8a770 243 243 // Mutex 244 244 struct cfathread_mutex { 245 single_acquisition_lock impl;245 fast_lock impl; 246 246 }; 247 247 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; } … … 258 258 // Condition 259 259 struct cfathread_condition { 260 condition_variable( single_acquisition_lock) impl;260 condition_variable(fast_lock) impl; 261 261 }; 262 262 int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; } -
libcfa/src/concurrency/invoke.h
ra6c45c6 r2d8a770 148 148 struct $thread * prev; 149 149 volatile unsigned long long ts; 150 unsigned preferred; 150 151 }; 151 152 … … 199 200 } node; 200 201 202 struct processor * last_proc; 203 201 204 #if defined( __CFA_WITH_VERIFY__ ) 202 205 void * canary; -
libcfa/src/concurrency/io.cfa
ra6c45c6 r2d8a770 40 40 #include "kernel.hfa" 41 41 #include "kernel/fwd.hfa" 42 #include "kernel_private.hfa" 42 43 #include "io/types.hfa" 43 44 … … 89 90 static inline unsigned __flush( struct $io_context & ); 90 91 static inline __u32 __release_sqes( struct $io_context & ); 92 extern void __kernel_unpark( $thread * thrd ); 91 93 92 94 bool __cfa_io_drain( processor * proc ) { 93 95 /* paranoid */ verify( ! __preemption_enabled() ); 96 /* paranoid */ verify( ready_schedule_islocked() ); 94 97 /* paranoid */ verify( proc ); 95 98 /* paranoid */ verify( proc->io.ctx ); … … 115 118 __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", &cqe, cqe.res, future ); 116 119 117 fulfil( *future, cqe.res);120 __kernel_unpark( fulfil( *future, cqe.res, false ) ); 118 121 } 119 122 … … 124 127 __atomic_store_n( ctx->cq.head, head + count, __ATOMIC_SEQ_CST ); 125 128 129 /* paranoid */ verify( ready_schedule_islocked() ); 126 130 /* paranoid */ verify( ! __preemption_enabled() ); 127 131 -
libcfa/src/concurrency/kernel.cfa
ra6c45c6 r2d8a770 34 34 #include "invoke.h" 35 35 36 #if !defined(__CFA_NO_STATISTICS__) 37 #define __STATS( ...) __VA_ARGS__ 38 #else 39 #define __STATS( ...) 40 #endif 36 41 37 42 //----------------------------------------------------------------------------- … … 166 171 preemption_scope scope = { this }; 167 172 168 #if !defined(__CFA_NO_STATISTICS__) 169 unsigned long long last_tally = rdtscl(); 170 #endif 173 __STATS( unsigned long long last_tally = rdtscl(); ) 171 174 172 175 // if we need to run some special setup, now is the time to do it. … … 266 269 __cfa_io_flush( this ); 267 270 } 271 272 // SEARCH: { 273 // /* paranoid */ verify( ! __preemption_enabled() ); 274 // /* paranoid */ verify( kernelTLS().this_proc_id ); 275 276 // // First, lock the scheduler since we are searching for a thread 277 278 // // Try to get the next thread 279 // ready_schedule_lock(); 280 // readyThread = pop_fast( this->cltr ); 281 // ready_schedule_unlock(); 282 // if(readyThread) { break SEARCH; } 283 284 // // If we can't find a thread, might as well flush any outstanding I/O 285 // if(this->io.pending) { __cfa_io_flush( this ); } 286 287 // // Spin a little on I/O, just in case 288 // for(25) { 289 // __maybe_io_drain( this ); 290 // ready_schedule_lock(); 291 // readyThread = pop_fast( this->cltr ); 292 // ready_schedule_unlock(); 293 // if(readyThread) { break SEARCH; } 294 // } 295 296 // // no luck, try stealing a few times 297 // for(25) { 298 // if( __maybe_io_drain( this ) ) { 299 // ready_schedule_lock(); 300 // readyThread = pop_fast( this->cltr ); 301 // } else { 302 // ready_schedule_lock(); 303 // readyThread = pop_slow( this->cltr ); 304 // } 305 // ready_schedule_unlock(); 306 // if(readyThread) { break SEARCH; } 307 // } 308 309 // // still no luck, search for a thread 310 // ready_schedule_lock(); 311 // readyThread = pop_search( this->cltr ); 312 // ready_schedule_unlock(); 313 // if(readyThread) { break SEARCH; } 314 315 // // Don't block if we are done 316 // if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 317 318 // __STATS( __tls_stats()->ready.sleep.halts++; ) 319 320 // // Push self to idle stack 321 // mark_idle(this->cltr->procs, * this); 322 323 // // Confirm the ready-queue is empty 324 // __maybe_io_drain( this ); 325 // ready_schedule_lock(); 326 // readyThread = pop_search( this->cltr ); 327 // ready_schedule_unlock(); 328 329 // if( readyThread ) { 330 // // A thread was found, cancel the halt 331 // mark_awake(this->cltr->procs, * this); 332 333 // __STATS( __tls_stats()->ready.sleep.cancels++; ) 334 335 // // continue the main loop 336 // break SEARCH; 337 // } 338 339 // __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl()); ) 340 // __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle); 341 342 // // __disable_interrupts_hard(); 343 // eventfd_t val; 344 // eventfd_read( this->idle, &val ); 345 // // __enable_interrupts_hard(); 346 347 // __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); ) 348 349 // // We were woken up, remove self from idle 350 // mark_awake(this->cltr->procs, * this); 351 352 // // DON'T just proceed, start looking again 353 // continue MAIN_LOOP; 354 // } 355 356 // RUN_THREAD: 357 // /* paranoid */ verify( kernelTLS().this_proc_id ); 358 // /* paranoid */ verify( ! __preemption_enabled() ); 359 // /* paranoid */ verify( readyThread ); 360 361 // // Reset io dirty bit 362 // this->io.dirty = false; 363 364 // // We found a thread run it 365 // __run_thread(this, readyThread); 366 367 // // Are we done? 368 // if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 369 370 // #if !defined(__CFA_NO_STATISTICS__) 371 // unsigned long long curr = rdtscl(); 372 // if(curr > (last_tally + 500000000)) { 373 // __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats); 374 // last_tally = curr; 375 // } 376 // #endif 377 378 // if(this->io.pending && !this->io.dirty) { 379 // __cfa_io_flush( this ); 380 // } 381 382 // // Check if there is pending io 383 // __maybe_io_drain( this ); 268 384 } 269 385 … … 402 518 $thread * thrd_src = kernelTLS().this_thread; 403 519 404 #if !defined(__CFA_NO_STATISTICS__) 405 struct processor * last_proc = kernelTLS().this_processor; 406 #endif 520 __STATS( thrd_src->last_proc = kernelTLS().this_processor; ) 407 521 408 522 // Run the thread on this processor … … 423 537 424 538 #if !defined(__CFA_NO_STATISTICS__) 425 if(last_proc != kernelTLS().this_processor) { 539 /* paranoid */ verify( thrd_src->last_proc != 0p ); 540 if(thrd_src->last_proc != kernelTLS().this_processor) { 426 541 __tls_stats()->ready.threads.migration++; 427 542 } … … 436 551 // Scheduler routines 437 552 // KERNEL ONLY 438 void __schedule_thread( $thread * thrd ) {553 static void __schedule_thread( $thread * thrd ) { 439 554 /* paranoid */ verify( ! __preemption_enabled() ); 440 555 /* paranoid */ verify( kernelTLS().this_proc_id ); … … 457 572 // Dereference the thread now because once we push it, there is not guaranteed it's still valid. 458 573 struct cluster * cl = thrd->curr_cluster; 574 __STATS(bool outside = thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; ) 459 575 460 576 // push the thread to the cluster ready-queue … … 470 586 if( kernelTLS().this_stats ) { 471 587 __tls_stats()->ready.threads.threads++; 588 if(outside) { 589 __tls_stats()->ready.threads.extunpark++; 590 } 472 591 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", kernelTLS().this_processor ); 473 592 } 474 593 else { 475 594 __atomic_fetch_add(&cl->stats->ready.threads.threads, 1, __ATOMIC_RELAXED); 595 __atomic_fetch_add(&cl->stats->ready.threads.extunpark, 1, __ATOMIC_RELAXED); 476 596 __push_stat( cl->stats, cl->stats->ready.threads.threads, true, "Cluster", cl ); 477 597 } … … 508 628 509 629 ready_schedule_lock(); 510 $thread * thrd = pop_slow( this ); 630 $thread * thrd; 631 for(25) { 632 thrd = pop_slow( this ); 633 if(thrd) goto RET; 634 } 635 thrd = pop_search( this ); 636 637 RET: 511 638 ready_schedule_unlock(); 512 639 … … 532 659 } 533 660 661 void __kernel_unpark( $thread * thrd ) { 662 /* paranoid */ verify( ! __preemption_enabled() ); 663 /* paranoid */ verify( ready_schedule_islocked()); 664 665 if( !thrd ) return; 666 667 if(__must_unpark(thrd)) { 668 // Wake lost the race, 669 __schedule_thread( thrd ); 670 } 671 672 /* paranoid */ verify( ready_schedule_islocked()); 673 /* paranoid */ verify( ! __preemption_enabled() ); 674 } 675 534 676 void unpark( $thread * thrd ) { 535 677 if( !thrd ) return; … … 744 886 745 887 static inline bool __maybe_io_drain( processor * proc ) { 888 bool ret = false; 746 889 #if defined(CFA_HAVE_LINUX_IO_URING_H) 747 890 __cfadbg_print_safe(runtime_core, "Kernel : core %p checking io for ring %d\n", proc, proc->io.ctx->fd); … … 752 895 unsigned tail = *ctx->cq.tail; 753 896 if(head == tail) return false; 754 return __cfa_io_drain( proc ); 897 ready_schedule_lock(); 898 ret = __cfa_io_drain( proc ); 899 ready_schedule_unlock(); 755 900 #endif 901 return ret; 756 902 } 757 903 -
libcfa/src/concurrency/kernel/startup.cfa
ra6c45c6 r2d8a770 447 447 link.next = 0p; 448 448 link.prev = 0p; 449 link.preferred = -1u; 450 last_proc = 0p; 449 451 #if defined( __CFA_WITH_VERIFY__ ) 450 452 canary = 0x0D15EA5E0D15EA5Ep; -
libcfa/src/concurrency/kernel_private.hfa
ra6c45c6 r2d8a770 284 284 285 285 //----------------------------------------------------------------------- 286 // pop thread from the ready queueof a cluster286 // pop thread from the local queues of a cluster 287 287 // returns 0p if empty 288 288 // May return 0p spuriously … … 290 290 291 291 //----------------------------------------------------------------------- 292 // pop thread from the ready queue of a cluster 292 // pop thread from any ready queue of a cluster 293 // returns 0p if empty 294 // May return 0p spuriously 295 __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr); 296 297 //----------------------------------------------------------------------- 298 // search all ready queues of a cluster for any thread 293 299 // returns 0p if empty 294 300 // guaranteed to find any threads added before this call 295 __attribute__((hot)) struct $thread * pop_s low(struct cluster * cltr);301 __attribute__((hot)) struct $thread * pop_search(struct cluster * cltr); 296 302 297 303 //----------------------------------------------------------------------- -
libcfa/src/concurrency/ready_queue.cfa
ra6c45c6 r2d8a770 344 344 } 345 345 346 __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) { 346 __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) { return pop_fast(cltr); } 347 __attribute__((hot)) struct $thread * pop_search(struct cluster * cltr) { 347 348 return search(cltr); 348 349 } … … 436 437 437 438 __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) with (cltr->ready_queue) { 438 for(25) { 439 unsigned i = __tls_rand() % lanes.count; 440 $thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal)); 441 if(t) return t; 442 } 443 439 unsigned i = __tls_rand() % lanes.count; 440 return try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal)); 441 } 442 443 __attribute__((hot)) struct $thread * pop_search(struct cluster * cltr) with (cltr->ready_queue) { 444 444 return search(cltr); 445 445 } -
libcfa/src/concurrency/stats.cfa
ra6c45c6 r2d8a770 38 38 stats->ready.pop.search.espec = 0; 39 39 stats->ready.threads.migration = 0; 40 stats->ready.threads.extunpark = 0; 40 41 stats->ready.threads.threads = 0; 41 42 stats->ready.sleep.halts = 0; … … 95 96 __atomic_fetch_add( &cltr->ready.pop.search.espec , proc->ready.pop.search.espec , __ATOMIC_SEQ_CST ); proc->ready.pop.search.espec = 0; 96 97 __atomic_fetch_add( &cltr->ready.threads.migration , proc->ready.threads.migration , __ATOMIC_SEQ_CST ); proc->ready.threads.migration = 0; 98 __atomic_fetch_add( &cltr->ready.threads.extunpark , proc->ready.threads.extunpark , __ATOMIC_SEQ_CST ); proc->ready.threads.extunpark = 0; 97 99 __atomic_fetch_add( &cltr->ready.threads.threads , proc->ready.threads.threads , __ATOMIC_SEQ_CST ); proc->ready.threads.threads = 0; 98 100 __atomic_fetch_add( &cltr->ready.sleep.halts , proc->ready.sleep.halts , __ATOMIC_SEQ_CST ); proc->ready.sleep.halts = 0; … … 124 126 125 127 char buf[1024]; 126 strstream sstr = { buf, 1024 };128 ostrstream sstr = { buf, 1024 }; 127 129 128 130 if( flags & CFA_STATS_READY_Q ) { … … 132 134 uint64_t totalR = ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success; 133 135 uint64_t totalS = ready.push.local.success + ready.push.share.success + ready.push.extrn.success; 134 sstr | "- totals : " | eng3(totalR) | "run," | eng3(totalS) | "schd (" | eng3(ready.push.extrn.success) | "ext," | eng3(ready.threads.migration) | "mig )";136 sstr | "- totals : " | eng3(totalR) | "run," | eng3(totalS) | "schd (" | eng3(ready.push.extrn.success) | "ext," | eng3(ready.threads.migration) | "mig," | eng3(ready.threads.extunpark) | " eupk)"; 135 137 136 138 double push_len = ((double)ready.push.local.attempt + ready.push.share.attempt + ready.push.extrn.attempt) / totalS; -
libcfa/src/concurrency/stats.hfa
ra6c45c6 r2d8a770 70 70 struct { 71 71 volatile uint64_t migration; 72 volatile uint64_t extunpark; 72 73 volatile int64_t threads; // number of threads in the system, includes only local change 73 74 } threads; -
libcfa/src/concurrency/thread.cfa
ra6c45c6 r2d8a770 39 39 link.next = 0p; 40 40 link.prev = 0p; 41 link.preferred = -1u; 42 last_proc = 0p; 41 43 #if defined( __CFA_WITH_VERIFY__ ) 42 44 canary = 0x0D15EA5E0D15EA5Ep; -
libcfa/src/fstream.cfa
ra6c45c6 r2d8a770 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 24 09:05:16202113 // Update Count : 4 2614 // 15 16 #include "fstream.hfa" 12 // Last Modified On : Wed Apr 28 20:37:53 2021 13 // Update Count : 445 14 // 15 16 #include "fstream.hfa" // also includes iostream.hfa 17 17 18 18 #include <stdio.h> // vfprintf, vfscanf … … 114 114 } // fail 115 115 116 void clear( ofstream & os ) { 117 clearerr( (FILE *)(os.file$) ); 118 } // clear 119 116 120 int flush( ofstream & os ) { 117 121 return fflush( (FILE *)(os.file$) ); … … 196 200 ofstream & abort = abortFile; 197 201 202 ofstream & nl( ofstream & os ) { 203 nl$( os ); // call basic_ostream nl 204 flush( os ); 205 return os; 206 // (ofstream &)(os | '\n'); 207 // setPrt$( os, false ); // turn off 208 // setNL$( os, true ); 209 // flush( os ); 210 // return sepOff( os ); // prepare for next line 211 } // nl 212 198 213 199 214 // *********************************** ifstream *********************************** … … 230 245 } // fail 231 246 247 void clear( ifstream & is ) { 248 clearerr( (FILE *)(is.file$) ); 249 } // clear 250 232 251 void ends( ifstream & is ) { 233 252 if ( is.acquired$ ) { is.acquired$ = false; release( is ); } 234 253 } // ends 235 254 236 inteof( ifstream & is ) {255 bool eof( ifstream & is ) { 237 256 return feof( (FILE *)(is.file$) ); 238 257 } // eof … … 263 282 } // close 264 283 265 ifstream & read( ifstream & is, char * data, size_t size ) {284 ifstream & read( ifstream & is, char data[], size_t size ) { 266 285 if ( fail( is ) ) { 267 286 abort | IO_MSG "attempt read I/O on failed stream"; -
libcfa/src/fstream.hfa
ra6c45c6 r2d8a770 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 24 09:04:03202113 // Update Count : 2 1912 // Last Modified On : Wed Apr 28 20:37:57 2021 13 // Update Count : 230 14 14 // 15 15 … … 70 70 71 71 bool fail( ofstream & ); 72 void clear( ofstream & ); 72 73 int flush( ofstream & ); 73 void open( ofstream &, const char name[], const char mode[] ); 74 void open( ofstream &, const char name[], const char mode[] ); // FIX ME: use default = "w" 74 75 void open( ofstream &, const char name[] ); 75 76 void close( ofstream & ); … … 86 87 87 88 void ?{}( ofstream & ); 88 void ?{}( ofstream &, const char name[], const char mode[] ); 89 void ?{}( ofstream &, const char name[], const char mode[] ); // FIX ME: use default = "w" 89 90 void ?{}( ofstream &, const char name[] ); 90 91 void ^?{}( ofstream & ); 92 93 // private 94 static inline ofstream & nl$( ofstream & os ) { return nl( os ); } // remember basic_ostream nl 95 // public 96 ofstream & nl( ofstream & os ); // override basic_ostream nl 91 97 92 98 extern ofstream & sout, & stdout, & serr, & stderr; // aliases … … 111 117 bool getANL( ifstream & ); 112 118 void ends( ifstream & ); 119 int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 120 113 121 bool fail( ifstream & is ); 114 int eof( ifstream & is ); 115 void open( ifstream & is, const char name[], const char mode[] ); 122 void clear( ifstream & ); 123 bool eof( ifstream & is ); 124 void open( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r" 116 125 void open( ifstream & is, const char name[] ); 117 126 void close( ifstream & is ); 118 ifstream & read( ifstream & is, char * data, size_t size );127 ifstream & read( ifstream & is, char data[], size_t size ); 119 128 ifstream & ungetc( ifstream & is, char c ); 120 int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 129 121 130 void acquire( ifstream & is ); 122 131 void release( ifstream & is ); … … 129 138 130 139 void ?{}( ifstream & is ); 131 void ?{}( ifstream & is, const char name[], const char mode[] ); 140 void ?{}( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r" 132 141 void ?{}( ifstream & is, const char name[] ); 133 142 void ^?{}( ifstream & is ); -
libcfa/src/iostream.cfa
ra6c45c6 r2d8a770 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 24 10:03:54202113 // Update Count : 13 2912 // Last Modified On : Tue Apr 27 18:01:03 2021 13 // Update Count : 1330 14 14 // 15 15 … … 145 145 } // ?|? 146 146 147 #if defined( __SIZEOF_INT128__ )147 #if defined( __SIZEOF_INT128__ ) 148 148 // UINT64_MAX 18_446_744_073_709_551_615_ULL 149 149 #define P10_UINT64 10_000_000_000_000_000_000_ULL // 19 zeroes 150 150 151 151 static inline void base10_128( ostype & os, unsigned int128 val ) { 152 #if defined(__GNUC__) && __GNUC_PREREQ(7,0)// gcc version >= 7152 #if defined(__GNUC__) && __GNUC_PREREQ(7,0) // gcc version >= 7 153 153 if ( val > P10_UINT64 ) { 154 #else154 #else 155 155 if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug 156 #endif // __GNUC_PREREQ(7,0)156 #endif // __GNUC_PREREQ(7,0) 157 157 base10_128( os, val / P10_UINT64 ); // recursive 158 158 fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) ); … … 187 187 (ostype &)(os | ullli); ends( os ); 188 188 } // ?|? 189 #endif // __SIZEOF_INT128__189 #endif // __SIZEOF_INT128__ 190 190 191 191 #define PrintWithDP( os, format, val, ... ) \ … … 361 361 setPrt$( os, false ); // turn off 362 362 setNL$( os, true ); 363 flush( os );364 363 return sepOff( os ); // prepare for next line 365 364 } // nl … … 808 807 809 808 810 forall( istype & | istream( istype ) ) {809 forall( istype & | basic_istream( istype ) ) { 811 810 istype & ?|?( istype & is, bool & b ) { 812 811 char val[6]; … … 918 917 } // ?|? 919 918 920 #if defined( __SIZEOF_INT128__ )919 #if defined( __SIZEOF_INT128__ ) 921 920 istype & ?|?( istype & is, int128 & llli ) { 922 921 return (istype &)(is | (unsigned int128 &)llli); … … 944 943 (istype &)(is | ullli); ends( is ); 945 944 } // ?|? 946 #endif // __SIZEOF_INT128__945 #endif // __SIZEOF_INT128__ 947 946 948 947 istype & ?|?( istype & is, float & f ) { … … 1035 1034 return is; 1036 1035 } // nlOff 1037 1036 } // distribution 1037 1038 forall( istype & | istream( istype ) ) { 1038 1039 istype & acquire( istype & is ) { 1039 1040 acquire( is ); // call void returning … … 1044 1045 // *********************************** manipulators *********************************** 1045 1046 1046 forall( istype & | istream( istype ) ) {1047 forall( istype & | basic_istream( istype ) ) { 1047 1048 istype & ?|?( istype & is, _Istream_Cstr f ) { 1048 1049 // skip xxx … … 1092 1093 1093 1094 #define InputFMTImpl( T, CODE ) \ 1094 forall( istype & | istream( istype ) ) { \1095 forall( istype & | basic_istream( istype ) ) { \ 1095 1096 istype & ?|?( istype & is, _Istream_Manip(T) f ) { \ 1096 1097 enum { size = 16 }; \ … … 1125 1126 InputFMTImpl( long double, "Lf" ) 1126 1127 1127 forall( istype & | istream( istype ) ) {1128 forall( istype & | basic_istream( istype ) ) { 1128 1129 istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) { 1129 1130 float re, im; -
libcfa/src/iostream.hfa
ra6c45c6 r2d8a770 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 25 11:22:03202113 // Update Count : 39712 // Last Modified On : Wed Apr 28 20:37:56 2021 13 // Update Count : 401 14 14 // 15 15 … … 49 49 void ends( ostype & ); // end of output statement 50 50 int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) )); 51 int flush( ostype & );52 51 }; // basic_ostream 53 52 54 53 trait ostream( ostype & | basic_ostream( ostype ) ) { 55 54 bool fail( ostype & ); // operation failed? 55 void clear( ostype & ); 56 int flush( ostype & ); 56 57 void open( ostype &, const char name[], const char mode[] ); 57 58 void close( ostype & ); … … 97 98 ostype & ?|?( ostype &, unsigned long long int ); 98 99 void ?|?( ostype &, unsigned long long int ); 99 #if defined( __SIZEOF_INT128__ )100 #if defined( __SIZEOF_INT128__ ) 100 101 ostype & ?|?( ostype &, int128 ); 101 102 void ?|?( ostype &, int128 ); 102 103 ostype & ?|?( ostype &, unsigned int128 ); 103 104 void ?|?( ostype &, unsigned int128 ); 104 #endif // __SIZEOF_INT128__105 #endif // __SIZEOF_INT128__ 105 106 106 107 ostype & ?|?( ostype &, float ); … … 121 122 void ?|?( ostype &, const char [] ); 122 123 // ostype & ?|?( ostype &, const char16_t * ); 123 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous124 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous 124 125 // ostype & ?|?( ostype &, const char32_t * ); 125 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )126 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) 126 127 // ostype & ?|?( ostype &, const wchar_t * ); 127 128 ostype & ?|?( ostype &, const void * ); … … 294 295 295 296 296 trait istream( istype & ) { 297 trait basic_istream( istype & ) { 298 bool getANL( istype & ); // get scan newline (on/off) 297 299 void nlOn( istype & ); // read newline 298 300 void nlOff( istype & ); // scan newline 299 bool getANL( istype & ); // get scan newline (on/off)300 301 301 302 void ends( istype & os ); // end of output statement 303 int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 304 istype & ungetc( istype &, char ); 305 bool eof( istype & ); 306 }; // basic_istream 307 308 trait istream( istype & | basic_istream( istype ) ) { 302 309 bool fail( istype & ); 303 int eof( istype & );310 void clear( istype & ); 304 311 void open( istype & is, const char name[] ); 305 312 void close( istype & is ); 306 istype & read( istype &, char *, size_t ); 307 istype & ungetc( istype &, char ); 308 int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 309 void acquire( istype & ); 313 istype & read( istype &, char [], size_t ); 314 void acquire( istype & ); // concurrent access 310 315 }; // istream 311 316 … … 314 319 }; // readable 315 320 316 forall( istype & | istream( istype ) ) {321 forall( istype & | basic_istream( istype ) ) { 317 322 istype & ?|?( istype &, bool & ); 318 323 void ?|?( istype &, bool & ); … … 341 346 istype & ?|?( istype &, unsigned long long int & ); 342 347 void ?|?( istype &, unsigned long long int & ); 343 #if defined( __SIZEOF_INT128__ )348 #if defined( __SIZEOF_INT128__ ) 344 349 istype & ?|?( istype &, int128 & ); 345 350 void ?|?( istype &, int128 & ); 346 351 istype & ?|?( istype &, unsigned int128 & ); 347 352 void ?|?( istype &, unsigned int128 & ); 348 #endif // __SIZEOF_INT128__353 #endif // __SIZEOF_INT128__ 349 354 350 355 istype & ?|?( istype &, float & ); … … 372 377 istype & nlOn( istype & ); 373 378 istype & nlOff( istype & ); 379 } // distribution 380 381 forall( istype & | istream( istype ) ) { 374 382 istype & acquire( istype & ); 375 383 } // distribution … … 402 410 _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; } 403 411 } // distribution 404 forall( istype & | istream( istype ) ) {412 forall( istype & | basic_istream( istype ) ) { 405 413 istype & ?|?( istype & is, _Istream_Cstr f ); 406 414 void ?|?( istype & is, _Istream_Cstr f ); … … 415 423 _Istream_Char & ignore( _Istream_Char & fmt ) { fmt.ignore = true; return fmt; } 416 424 } // distribution 417 forall( istype & | istream( istype ) ) {425 forall( istype & | basic_istream( istype ) ) { 418 426 istype & ?|?( istype & is, _Istream_Char f ); 419 427 void ?|?( istype & is, _Istream_Char f ); … … 434 442 _Istream_Manip(T) & wdi( unsigned int w, _Istream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \ 435 443 } /* distribution */ \ 436 forall( istype & | istream( istype ) ) { \444 forall( istype & | basic_istream( istype ) ) { \ 437 445 istype & ?|?( istype & is, _Istream_Manip(T) f ); \ 438 446 void ?|?( istype & is, _Istream_Manip(T) f ); \ -
libcfa/src/strstream.cfa
ra6c45c6 r2d8a770 10 10 // Created On : Thu Apr 22 22:24:35 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 24 11:15:47202113 // Update Count : 7 312 // Last Modified On : Tue Apr 27 20:59:53 2021 13 // Update Count : 78 14 14 // 15 15 … … 23 23 #include <unistd.h> // sbrk, sysconf 24 24 25 25 26 // *********************************** strstream *********************************** 26 27 … … 29 30 30 31 // private 31 bool sepPrt$( strstream & os ) { setNL$( os, false ); return os.sepOnOff$; }32 void sepReset$( strstream & os ) { os.sepOnOff$ = os.sepDefault$; }33 void sepReset$( strstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }34 const char * sepGetCur$( strstream & os ) { return os.sepCur$; }35 void sepSetCur$( strstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }36 bool getNL$( strstream & os ) { return os.sawNL$; }37 void setNL$( strstream & os, bool state ) { os.sawNL$ = state; }38 bool getANL$( strstream & os ) { return os.nlOnOff$; }39 bool getPrt$( strstream & os ) { return os.prt$; }40 void setPrt$( strstream & os, bool state ) { os.prt$ = state; }32 bool sepPrt$( ostrstream & os ) { setNL$( os, false ); return os.sepOnOff$; } 33 void sepReset$( ostrstream & os ) { os.sepOnOff$ = os.sepDefault$; } 34 void sepReset$( ostrstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; } 35 const char * sepGetCur$( ostrstream & os ) { return os.sepCur$; } 36 void sepSetCur$( ostrstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; } 37 bool getNL$( ostrstream & os ) { return os.sawNL$; } 38 void setNL$( ostrstream & os, bool state ) { os.sawNL$ = state; } 39 bool getANL$( ostrstream & os ) { return os.nlOnOff$; } 40 bool getPrt$( ostrstream & os ) { return os.prt$; } 41 void setPrt$( ostrstream & os, bool state ) { os.prt$ = state; } 41 42 42 43 // public 43 void ?{}( strstream & os, char buf[], size_t size ) {44 void ?{}( ostrstream & os, char buf[], size_t size ) { 44 45 os.buf$ = buf; 45 46 os.size$ = size; … … 55 56 } // ?{} 56 57 57 void sepOn( strstream & os ) { os.sepOnOff$ = ! getNL$( os ); }58 void sepOff( strstream & os ) { os.sepOnOff$ = false; }58 void sepOn( ostrstream & os ) { os.sepOnOff$ = ! getNL$( os ); } 59 void sepOff( ostrstream & os ) { os.sepOnOff$ = false; } 59 60 60 bool sepDisable( strstream & os ) {61 bool sepDisable( ostrstream & os ) { 61 62 bool temp = os.sepDefault$; 62 63 os.sepDefault$ = false; … … 65 66 } // sepDisable 66 67 67 bool sepEnable( strstream & os ) {68 bool sepEnable( ostrstream & os ) { 68 69 bool temp = os.sepDefault$; 69 70 os.sepDefault$ = true; … … 72 73 } // sepEnable 73 74 74 void nlOn( strstream & os ) { os.nlOnOff$ = true; }75 void nlOff( strstream & os ) { os.nlOnOff$ = false; }75 void nlOn( ostrstream & os ) { os.nlOnOff$ = true; } 76 void nlOff( ostrstream & os ) { os.nlOnOff$ = false; } 76 77 77 const char * sepGet( strstream & os ) { return os.separator$; }78 void sepSet( strstream & os, const char s[] ) {78 const char * sepGet( ostrstream & os ) { return os.separator$; } 79 void sepSet( ostrstream & os, const char s[] ) { 79 80 assert( s ); 80 strncpy( os.separator$, s, strstream_sepSize - 1 );81 os.separator$[ strstream_sepSize - 1] = '\0';81 strncpy( os.separator$, s, ostrstream_sepSize - 1 ); 82 os.separator$[ostrstream_sepSize - 1] = '\0'; 82 83 } // sepSet 83 84 84 const char * sepGetTuple( strstream & os ) { return os.tupleSeparator$; }85 void sepSetTuple( strstream & os, const char s[] ) {85 const char * sepGetTuple( ostrstream & os ) { return os.tupleSeparator$; } 86 void sepSetTuple( ostrstream & os, const char s[] ) { 86 87 assert( s ); 87 strncpy( os.tupleSeparator$, s, strstream_sepSize - 1 );88 os.tupleSeparator$[ strstream_sepSize - 1] = '\0';88 strncpy( os.tupleSeparator$, s, ostrstream_sepSize - 1 ); 89 os.tupleSeparator$[ostrstream_sepSize - 1] = '\0'; 89 90 } // sepSet 90 91 91 void ends( strstream & os ) {92 void ends( ostrstream & os ) { 92 93 if ( getANL$( os ) ) nl( os ); 93 94 else setPrt$( os, false ); // turn off 94 95 } // ends 95 96 96 int fmt( strstream & os, const char format[], ... ) {97 int fmt( ostrstream & os, const char format[], ... ) { 97 98 va_list args; 98 99 va_start( args, format ); 99 100 int len = vsnprintf( os.buf$ + os.cursor$, os.size$ - os.cursor$, format, args ); 101 va_end( args ); 100 102 os.cursor$ += len; 101 103 if ( os.cursor$ >= os.size$ ) { // cursor exceeded buffer size? 102 #define fmtmsg IO_MSG " strstream truncated write, buffer too small.\n"104 #define fmtmsg IO_MSG "ostrstream truncated write, buffer too small.\n" 103 105 write( STDERR_FILENO, fmtmsg, sizeof(fmtmsg) - 1 ); 104 106 abort(); 105 107 } // if 106 va_end( args );107 108 108 109 setPrt$( os, true ); // called in output cascade … … 111 112 } // fmt 112 113 113 int flush( strstream & ) { // match trait, not used 114 return 0; 115 } // flush 116 117 strstream & write( strstream & os ) { 118 return write( os, stdout ); 119 } // write 120 strstream & write( strstream & os, FILE * stream ) { 114 ostrstream & write( ostrstream & os, FILE * stream ) { 121 115 if ( fwrite( os.buf$, 1, os.cursor$, stream ) != os.cursor$ ) { 122 #define writemsg IO_MSG "strstream write error.\n"123 write( STDERR_FILENO, writemsg, sizeof(writemsg) - 1 );116 #define ostrwritemsg IO_MSG "ostrstream write error.\n" 117 write( STDERR_FILENO, ostrwritemsg, sizeof(ostrwritemsg) - 1 ); 124 118 abort(); 125 119 } // if … … 127 121 } // write 128 122 129 strstream & sstr; 123 ostrstream & write( ostrstream & os ) { 124 return write( os, stdout ); 125 } // write 126 127 128 // *********************************** istrstream *********************************** 129 130 131 // public 132 void ?{}( istrstream & is, char buf[] ) { 133 is.buf$ = buf; 134 is.cursor$ = 0; 135 is.nlOnOff$ = false; 136 } // ?{} 137 138 bool getANL( istrstream & is ) { return is.nlOnOff$; } 139 void nlOn( istrstream & is ) { is.nlOnOff$ = true; } 140 void nlOff( istrstream & is ) { is.nlOnOff$ = false; } 141 142 void ends( istrstream & is ) { 143 } // ends 144 145 int eof( istrstream & is ) { 146 return 0; 147 } // eof 148 149 istrstream &ungetc( istrstream & is, char c ) { 150 // if ( ungetc( c, (FILE *)(is.file$) ) == EOF ) { 151 // abort | IO_MSG "ungetc" | nl | strerror( errno ); 152 // } // if 153 return is; 154 } // ungetc 155 156 int fmt( istrstream & is, const char format[], ... ) { 157 va_list args; 158 va_start( args, format ); 159 // This does not work because vsscanf does not return buffer position. 160 int len = vsscanf( is.buf$ + is.cursor$, format, args ); 161 va_end( args ); 162 if ( len == EOF ) { 163 int j; 164 printf( "X %d%n\n", len, &j ); 165 } // if 166 is.cursor$ += len; 167 return len; 168 } // fmt 130 169 131 170 // Local Variables: // -
libcfa/src/strstream.hfa
ra6c45c6 r2d8a770 10 10 // Created On : Thu Apr 22 22:20:59 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 24 11:17:33202113 // Update Count : 3712 // Last Modified On : Tue Apr 27 20:58:50 2021 13 // Update Count : 41 14 14 // 15 15 … … 20 20 21 21 22 // *********************************** strstream ***********************************22 // *********************************** ostrstream *********************************** 23 23 24 24 25 enum { strstream_sepSize = 16 };26 struct strstream { // satisfied basic_ostream25 enum { ostrstream_sepSize = 16 }; 26 struct ostrstream { // satisfied basic_ostream 27 27 char * buf$; 28 28 size_t size$; … … 34 34 bool sawNL$; 35 35 const char * sepCur$; 36 char separator$[ strstream_sepSize];37 char tupleSeparator$[ strstream_sepSize];38 }; // strstream36 char separator$[ostrstream_sepSize]; 37 char tupleSeparator$[ostrstream_sepSize]; 38 }; // ostrstream 39 39 40 40 // Satisfies basic_ostream 41 41 42 42 // private 43 bool sepPrt$( strstream & );44 void sepReset$( strstream & );45 void sepReset$( strstream &, bool );46 const char * sepGetCur$( strstream & );47 void sepSetCur$( strstream &, const char [] );48 bool getNL$( strstream & );49 void setNL$( strstream &, bool );50 bool getANL$( strstream & );51 bool getPrt$( strstream & );52 void setPrt$( strstream &, bool );43 bool sepPrt$( ostrstream & ); 44 void sepReset$( ostrstream & ); 45 void sepReset$( ostrstream &, bool ); 46 const char * sepGetCur$( ostrstream & ); 47 void sepSetCur$( ostrstream &, const char [] ); 48 bool getNL$( ostrstream & ); 49 void setNL$( ostrstream &, bool ); 50 bool getANL$( ostrstream & ); 51 bool getPrt$( ostrstream & ); 52 void setPrt$( ostrstream &, bool ); 53 53 54 54 // public 55 void sepOn( strstream & );56 void sepOff( strstream & );57 bool sepDisable( strstream & );58 bool sepEnable( strstream & );59 void nlOn( strstream & );60 void nlOff( strstream & );55 void sepOn( ostrstream & ); 56 void sepOff( ostrstream & ); 57 bool sepDisable( ostrstream & ); 58 bool sepEnable( ostrstream & ); 59 void nlOn( ostrstream & ); 60 void nlOff( ostrstream & ); 61 61 62 const char * sepGet( strstream & );63 void sepSet( strstream &, const char [] );64 const char * sepGetTuple( strstream & );65 void sepSetTuple( strstream &, const char [] );62 const char * sepGet( ostrstream & ); 63 void sepSet( ostrstream &, const char [] ); 64 const char * sepGetTuple( ostrstream & ); 65 void sepSetTuple( ostrstream &, const char [] ); 66 66 67 void ends( strstream & ); 68 int fmt( strstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) )); 69 int flush( strstream & ); 67 void ends( ostrstream & ); 68 int fmt( ostrstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) )); 70 69 71 strstream & write( strstream & os ); // use stdout, default value not working 72 strstream & write( strstream & os, FILE * stream = stdout);70 ostrstream & write( ostrstream & os, FILE * stream ); // FIX ME: use default = stdout 71 ostrstream & write( ostrstream & os ); 73 72 74 void ?{}( strstream &, char buf[], size_t size );73 void ?{}( ostrstream &, char buf[], size_t size ); 75 74 76 extern strstream & sstr; 75 76 // *********************************** istrstream *********************************** 77 78 79 struct istrstream { 80 char * buf$; 81 size_t cursor$; 82 bool nlOnOff$; 83 }; // istrstream 84 85 // Satisfies basic_istream 86 87 // public 88 bool getANL( istrstream & ); 89 void nlOn( istrstream & ); 90 void nlOff( istrstream & ); 91 void ends( istrstream & ); 92 int fmt( istrstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 93 istrstream & ungetc( istrstream & is, char c ); 94 int eof( istrstream & is ); 95 96 void ?{}( istrstream & is, char buf[] ); 77 97 78 98 // Local Variables: // -
src/Parser/parser.yy
ra6c45c6 r2d8a770 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 14 18:13:44 202113 // Update Count : 49 8312 // Last Modified On : Mon Apr 26 18:41:54 2021 13 // Update Count : 4990 14 14 // 15 15 … … 211 211 } // forCtrl 212 212 213 bool forall = false , yyy = false;// aggregate have one or more forall qualifiers ?213 bool forall = false; // aggregate have one or more forall qualifiers ? 214 214 215 215 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type … … 812 812 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 813 813 | '(' aggregate_control '&' ')' cast_expression // CFA 814 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 815 | '(' aggregate_control '*' ')' cast_expression // CFA 814 816 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 815 817 | '(' VIRTUAL ')' cast_expression // CFA … … 2128 2130 aggregate_data: 2129 2131 STRUCT vtable_opt 2130 { yyy = true;$$ = AggregateDecl::Struct; }2132 { $$ = AggregateDecl::Struct; } 2131 2133 | UNION 2132 { yyy = true;$$ = AggregateDecl::Union; }2134 { $$ = AggregateDecl::Union; } 2133 2135 | EXCEPTION // CFA 2134 { yyy = true;$$ = AggregateDecl::Exception; }2136 { $$ = AggregateDecl::Exception; } 2135 2137 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2136 2138 ; … … 2138 2140 aggregate_control: // CFA 2139 2141 MONITOR 2140 { yyy = true;$$ = AggregateDecl::Monitor; }2142 { $$ = AggregateDecl::Monitor; } 2141 2143 | MUTEX STRUCT 2142 { yyy = true;$$ = AggregateDecl::Monitor; }2144 { $$ = AggregateDecl::Monitor; } 2143 2145 | GENERATOR 2144 { yyy = true;$$ = AggregateDecl::Generator; }2146 { $$ = AggregateDecl::Generator; } 2145 2147 | MUTEX GENERATOR 2146 2148 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2147 2149 | COROUTINE 2148 { yyy = true;$$ = AggregateDecl::Coroutine; }2150 { $$ = AggregateDecl::Coroutine; } 2149 2151 | MUTEX COROUTINE 2150 2152 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2151 2153 | THREAD 2152 { yyy = true;$$ = AggregateDecl::Thread; }2154 { $$ = AggregateDecl::Thread; } 2153 2155 | MUTEX THREAD 2154 2156 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } -
tests/io/io-acquire.cfa
ra6c45c6 r2d8a770 10 10 // Created On : Mon Mar 1 18:40:09 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 2 12:06:35202113 // Update Count : 1 712 // Last Modified On : Tue Apr 27 11:49:34 2021 13 // Update Count : 18 14 14 // 15 15 … … 43 43 int a, b, c, d, e, f, g, h, i; 44 44 for ( 100 ) { // local protection 45 sin 45 sin | acquire | a | b | c | d | e | f | g | h | i; 46 46 } 47 47 { // global protection (RAII) -
tests/strstream.cfa
ra6c45c6 r2d8a770 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo 3 // 4 // strstream.cfa -- 5 // 6 // Author : Peter A. Buhr 7 // Created On : Wed Apr 28 21:47:35 2021 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Wed Apr 28 21:50:02 2021 10 // Update Count : 3 11 // 12 1 13 #include <fstream.hfa> 2 14 #include <strstream.hfa> 3 15 4 16 int main() { 5 6 char buf[size]; 7 strstream sstr = { buf, size }; 8 9 17 enum { size = 256 }; 18 char buf[size]; // output buffer 19 ostrstream osstr = { buf, size }; // bind output buffer/size 20 int i = 3, j = 5, k = 7; 21 double x = 12345678.9, y = 98765.4321e-11; 10 22 11 sstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); 12 write( sstr ); 13 printf( "%s", buf ); 14 sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); 23 osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); // same lines of output 24 write( osstr ); 25 printf( "%s", buf ); 26 sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y)); 27 28 // char buf2[] = "12 14 15 3.5 7e4"; // input buffer 29 // istrstream isstr = { buf2 }; 30 // isstr | i | j | k | x | y; 31 // sout | i | j | k | x | y; 15 32 } 33 34 // Local Variables: // 35 // tab-width: 4 // 36 // compile-command: "cfa strstream.cfa" // 37 // End: //
Note:
See TracChangeset
for help on using the changeset viewer.