Changes in / [75d874a:0e16a2d]
- Files:
-
- 1 added
- 20 edited
-
doc/theses/mike_brooks_MMath/list.tex (modified) (18 diffs)
-
doc/theses/mike_brooks_MMath/uw-ethesis.tex (modified) (4 diffs)
-
libcfa/src/bits/random.hfa (modified) (12 diffs)
-
libcfa/src/concurrency/channel.hfa (modified) (12 diffs)
-
libcfa/src/concurrency/io.cfa (modified) (1 diff)
-
libcfa/src/concurrency/io/call.cfa.in (modified) (11 diffs)
-
libcfa/src/concurrency/locks.hfa (modified) (5 diffs)
-
src/AST/Print.cpp (modified) (1 diff)
-
src/Common/Debug.h (added)
-
src/Common/module.mk (modified) (1 diff)
-
src/Common/utility.h (modified) (1 diff)
-
src/InitTweak/FixInit.cc (modified) (1 diff)
-
src/InitTweak/FixInitNew.cpp (modified) (1 diff)
-
src/Parser/parser.yy (modified) (12 diffs)
-
src/SynTree/FunctionDecl.cc (modified) (1 diff)
-
tests/.expect/PRNG.x64.txt (modified) (3 diffs)
-
tests/.expect/PRNG.x86.txt (modified) (1 diff)
-
tests/.expect/nested_function.x86.txt (modified) (1 diff)
-
tests/concurrent/channels/parallel_harness.hfa (modified) (3 diffs)
-
tests/concurrent/pthread/.expect/bounded_buffer.x64.txt (modified) (1 diff)
-
tests/concurrent/pthread/.expect/bounded_buffer.x86.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/list.tex
r75d874a r0e16a2d 13 13 14 14 15 15 16 \section{Design Issues} 16 17 \label{toc:lst:issue} … … 19 20 20 21 All design-issue discussions assume the following invariants. 21 \PAB{They are stated here to clarify that none of the discussed design issues refers to one of these.} 22 They are stated here to clarify that none of the discussed design issues refers to one of these. 22 23 Alternatives to the assumptions are discussed under Future Work (Section~\ref{toc:lst:futwork}). 23 24 \begin{itemize} … … 29 30 The system has freedom over how to represent these links. 30 31 The library is not providing applied wrapper operations that consume a user's hand-implemented list primitives. 31 \item \PAB{These issues are compared at a requirement/functional level.}32 \item These issues are compared at a requirement/functional level. 32 33 \end{itemize} 33 34 34 35 Two preexisting linked-list libraries are used throughout, to show examples of the concepts being defined, 35 36 and further libraries are introduced as needed. 37 A general comparison of libraries' abilities is given under Related Work (Section~\ref{toc:lst:relwork}). 36 38 \begin{description} 37 39 \item[LQ] Linux Queue library\cite{lst:linuxq} of @<sys/queue.h>@. 38 40 \item[STL] C++ Standard Template Library's @std::list@\cite{lst:stl} 39 41 \end{description} 40 A general comparison of libraries' abilities is given under Related Work (Section~\ref{toc:lst:relwork}).41 42 42 43 The fictional type @req@ (request) is the user's payload in examples. … … 57 58 58 59 The wrapped style admits the further distinction between wrapping a reference and wrapping a value. 59 This distinction is pervasive in all STL collections; @list<req *>@ wraps a reference; @list<req>@ wraps a value.60 (For this discussion, @list<req &>@ is similar to @list<req*>@.)60 This distinction is pervasive in all STL collections; @list<req*>@ wraps a reference; @list<req>@ wraps a value. 61 (For this discussion, @list<req&>@ is similar to @list<req*>@.) 61 62 This difference is one of user style, not framework capability. 62 Figure~\ref{fig:lst-issues-attach} compares the three styles. 63 64 \begin{comment} 63 65 64 \begin{figure} 66 65 \begin{tabularx}{\textwidth}{Y|Y|Y}\lstinputlisting[language=C , firstline=20, lastline=39]{lst-issues-intrusive.run.c} … … 78 77 (a) & (b) & (c) 79 78 \end{tabularx} 80 \caption{79 \caption{ 81 80 Three styles of link attachment: (a)~intrusive, (b)~wrapped reference, and (c)~wrapped value. 82 81 The diagrams show the memory layouts that result after the code runs, eliding the head object \lstinline{reqs}; … … 88 87 (TODO: cite? found in /usr/include/c++/7/bits/stl\_list.h ) 89 88 } 90 \label{fig:lst-issues-attach}91 \end{figure}92 \end{comment}93 94 \begin{figure}95 \centering96 \newsavebox{\myboxA} % used with subfigure97 \newsavebox{\myboxB}98 \newsavebox{\myboxC}99 100 \begin{lrbox}{\myboxA}101 \begin{tabular}{@{}l@{}}102 \lstinputlisting[language=C, firstline=20, lastline=39]{lst-issues-intrusive.run.c} \\103 \ \\104 \includegraphics[page=1]{lst-issues-attach.pdf}105 \end{tabular}106 \end{lrbox}107 108 \begin{lrbox}{\myboxB}109 \begin{tabular}{@{}l@{}}110 \lstinputlisting[language=C++, firstline=20, lastline=39]{lst-issues-wrapped-byref.run.cpp} \\111 \ \\112 \includegraphics[page=2]{lst-issues-attach.pdf}113 \end{tabular}114 \end{lrbox}115 116 \begin{lrbox}{\myboxC}117 \begin{tabular}{@{}l@{}}118 \lstinputlisting[language=C++, firstline=20, lastline=39]{lst-issues-wrapped-emplaced.run.cpp} \\119 \ \\120 \includegraphics[page=3]{lst-issues-attach.pdf}121 \end{tabular}122 \end{lrbox}123 124 \subfloat[Intrusive]{\label{f:Intrusive}\usebox\myboxA}125 \hspace{10pt}126 \vrule127 \hspace{10pt}128 \subfloat[Wrapped reference]{\label{f:WrappedRef}\usebox\myboxB}129 \hspace{10pt}130 \vrule131 \hspace{10pt}132 \subfloat[Wrapped value]{\label{f:WrappedValue}\usebox\myboxC}133 134 \caption{135 Three styles of link attachment: \protect\subref*{f:Intrusive}~intrusive, \protect\subref*{f:WrappedRef}~wrapped136 reference, and \protect\subref*{f:WrappedValue}~wrapped value.137 The diagrams show the memory layouts that result after the code runs, eliding the head object \lstinline{reqs};138 head objects are discussed in Section~\ref{toc:lst:issue:ident}.139 In \protect\subref*{f:Intrusive}, the field \lstinline{req.x} names a list direction;140 these are discussed in Section~\ref{toc:lst:issue:derection}.141 In \protect\subref*{f:WrappedRef} and \protect\subref*{f:WrappedValue}, the type \lstinline{node} represents a142 system-internal type, which is \lstinline{std::_List_node} in the GNU implementation.143 (TODO: cite? found in /usr/include/c++/7/bits/stl\_list.h )144 }145 89 \label{fig:lst-issues-attach} 146 90 \end{figure} 91 92 93 Figure~\ref{fig:lst-issues-attach} compares the three styles. 147 94 148 95 The advantage of intrusive attachment is the control that it gives the user over memory layout. … … 150 97 Both wrapped attachment styles imply system-induced heap allocations. 151 98 Such an allocation has a lifetime that matches the item's membership in the list. 152 In \subref*{f:Intrusive} and \subref*{f:WrappedRef}, one @req@ object can enter and leave a list many times.153 In \subref*{f:WrappedRef}, it implies a dynamic allocation/deallocation for each enter/leave; in \subref*{f:Intrusive}, it does not.99 In (a) and (b), one @req@ object can enter and leave a list many times. 100 In (b), doing do implies a dynamic allocation for each time joining; in (a), it does not. 154 101 155 102 A further aspect of layout control is allowing the user to specify the location of the link fields within the @req@ object. … … 163 110 Another subtle advantage of intrusive arrangement is that 164 111 a reference to a user-level item (@req@) is sufficient to navigate or manage the item's membership. 165 In LQ, \subref*{f:Intrusive}, a @req@ pointer is the right argument type for operations @LIST_NEXT@ or @LIST_REMOVE@;112 In LQ, (a), a @req@ pointer is the right argument type for operations @LIST_NEXT@ or @LIST_REMOVE@; 166 113 there is no distinguishing a @req@ from ``a @req@ in a list.'' 167 The same is not true of STL, \subref*{f:WrappedRef} or \subref*{f:WrappedValue}.114 The same is not true of STL, (b) or (c). 168 115 There, the analogous operations work on a parameter of type @list<T>::iterator@; 169 116 they are @iterator::operator++()@, @iterator::operator*()@, and @list::erase(iterator)@. 170 There is no mapping from @req &@ to @list<req>::iterator@, except for linear search.117 There is no mapping from @req&@ to @list<req>::iterator@, except for linear search. 171 118 172 119 The advantage of wrapped attachment is the abstraction of a data item from its list membership(s). 173 120 In the wrapped style, the @req@ type can come from a library that serves many independent uses, 174 121 which generally have no need for listing. 175 Then, a novel use can still put @req@ in a (further) list, without requiring any upstream change in the @re q@ library.122 Then, a novel use can still put @req@ in a (further) list, without requiring any upstream change in the @re@ library. 176 123 In intrusive attachment, the ability to be listed must be planned during the definition of @req@. 177 Similarly, style \subref*{f:WrappedRef} allows for one @req@ to occur at several positions in one list. 178 Styles \subref*{f:Intrusive} and \subref*{f:WrappedValue} do not support this ability. 179 \PAB{But style \subref*{f:WrappedValue} can sort of mimic this effect by have multiple copies of \lstinline{req} in the list, modulo changes to the copies are not seen by the original.} 124 Similarly, style (b) allows for one @req@ to occur at several positions in one list. 125 Styles (a) and (c) do not support this ability. 180 126 181 127 \begin{figure} … … 189 135 the LQ C macros do not expand to valid C++ when instantiated with template parameters---there is no \lstinline{struct El}. 190 136 When using a custom-patched version of LQ to work around this issue, 191 the programs of Figure~\ref{f :WrappedRef} and \protect\subref*{f:WrappedValue}work with this shim in place of real STL.137 the programs of Figure~\ref{fig:lst-issues-attach}~(b) and (c) work with this shim in place of real STL. 192 138 Their executions lead to the same memory layouts. 193 139 } … … 201 147 202 148 So intrusion is a lower-level listing primitive. 203 And so, the system design choice is not between forcing users to use intrusion orwrapping.149 And so, the system design choice is not between forcing users to use intrusion and forcing them to use wrapping. 204 150 The choice is whether or not to provide access to an allocation-free layer of functionality. 205 151 A wrapped-primitive library like STL forces users to incur the costs of wrapping, whether or not they access its benefits. … … 207 153 208 154 155 156 209 157 \subsection{Directionality: Single vs.\ Multi-Static vs.\ Dynamic} 210 158 \label{toc:lst:issue:derection} 211 159 212 \PAB{I'm not sure about the term \newterm{Directionality}. Directionality to me, means going forward or backwards through a list.213 Would \newterm{dimensionality} work? Think of each list containing the node as a different dimension in which the node sits.}214 215 160 Directionality deals with the question: 216 161 In how many different lists can an item be stored, at a given time? 217 162 218 Consider STL in the wrapped-value arrangement of Figure~\ref{f:WrappedValue}. 163 164 Consider STL in the wrapped-value arrangement of Figure~\ref{fig:lst-issues-attach}~(c). 219 165 The STL API completely hides its @node@ type from a user; the user cannot configure this choice or impose a custom one. 220 166 STL's @node@ type offers the sole set of links shown in the diagram. 221 Therefore, every @req@ in existence is allocated either to belong to an occurrence of the diagrammed arrangement,167 Therefore, every @req@ in existence was allocated either to belong to an occurrence of the diagrammed arrangement, 222 168 or to be apart from all occurrences of it. 223 169 In the first case, the @req@ belongs to exactly one list (of the style in question). … … 225 171 226 172 \begin{figure} 173 \label{fig:lst-issues-multi-static} 227 174 \parbox[t]{3.5in} { 228 175 \lstinputlisting[language=C++, firstline=20, lastline=60]{lst-issues-multi-static.run.c} … … 240 187 The zoomed-in diagram portion shows the field-level state that results from running the LQ code. 241 188 } 242 \label{fig:lst-issues-multi-static}243 189 \end{figure} 244 190 … … 259 205 The corresponding flexibility of wrapped attachment means 260 206 the STL wrapped-reference arrangement supports an item being a member of arbitrarily many lists. 261 This support also applies to the wrapped-value list because the @req@ is copied,207 This support also applies to the hybrid in which an item's allocation is within a wrapped-value list, 262 208 but wrapped-reference lists provide further link directions. 263 \PAB{Explain how}264 209 STL with wrapped references supports dynamic link directions. 265 \PAB{Expand} 266 267 When allowing multiple static directions, frameworks differ in their ergonomics for 268 the typical case: when the user needs only one direction, vs.\ the atypical case, when the user needs several. 210 211 When allowing multiple static directions,frameworks differ in their ergonomics for 212 the typical case, when the user needs only one direction, vs.\ the atypical case, when the user needs several. 213 269 214 LQ's ergonomics are well-suited to the uncommon case of multiple list directions. 270 215 Its intrusion declaration and insertion operation both use a mandatory explicit parameter naming the direction. 271 216 This decision works well in Figure~\ref{fig:lst-issues-multi-static}, where the names @by_pri@ and @by_rqr@ work well, 272 but it clutters Figure~\ref{f :Intrusive}, where a contrived name must be invented and used.273 The example uses @x@; @reqs@ would be a more readily ignored choice. \PAB{wording?}217 but it clutters Figure~\ref{fig:lst-issues-attach}~(a), where a contrived name must be invented and used. 218 The example uses @x@; @reqs@ would be a more readily ignored choice. 274 219 275 220 \uCpp offers an intrusive list that makes the opposite choice. TODO: elaborate on inheritance for first direction and acrobatics for subsequent directions. 276 221 277 222 223 224 278 225 \subsection{User integration: Preprocessed vs.\ Type-System Mediated} 279 226 280 227 % example of poor error message due to LQ's preprocessed integration 281 % programs/lst-issues-multi-static.run.c:46:1: error: expected identifier or '(' before 'do'228 % programs/lst-issues-multi-static.run.c:46:1: error: expected identifier or ‘(’ before ‘do’ 282 229 % 46 | LIST_INSERT_HEAD(&reqs_rtr_42, &r42b, by_rqr); 283 230 % | ^~~~~~~~~~~~~~~~ … … 292 239 an item found in a list (type @req@, of variables like @r1@), and 293 240 a list (type @reql@ or @list<req>@, of variables like @reqs@ or @reqs_rqr_42@). 294 \see{Figure~\ref{fig:lst-issues-attach} and Figure~\ref{fig:lst-issues-multi-static}} 295 The latter type is a head, and these examples are of headed lists. 241 The latter type is a head, and these examples are of are headed lists. 296 242 297 243 A bespoke ``pointer to next @req@'' implementation often omits the latter type. … … 300 246 In headed thinking, there are length-zero lists (heads with no elements), and an element can be listed or not listed. 301 247 In ad-hoc thinking, there are no length-zero lists and every element belongs to a list of length at least one. 302 \PAB{Create a figure for this.}303 248 304 249 By omitting the head, elements can enter into an adjacency relationship, … … 338 283 identifies a list using an explicit head. 339 284 340 The \CFA list library's version of the running @req@ example is in Figure~\ref{fig:lst-features-intro}. 341 Its link attachment is intrusive and the resulting memory layout is pure-stack, just as for the LQ version of Figure~\ref{f:Intrusive}. 342 The framework-provided type @dlink(...)@ provides the links. 343 The user inserts the links into the @req@ structure by using \CFA inline-inheritance (TODO: reference introduction). 344 Inline inheritance means the type of the field is @dlink(req)@, the field is unnamed, a reference to a @req@ is implicitly convertible to @dlink@.\footnote{ 285 286 \begin{figure} 287 \label{fig:lst-features-intro} 288 \lstinputlisting[language=CFA, firstline=20, lastline=32]{lst-features-intro.run.cfa} 289 \caption[Multiple link directions in \CFA list library]{ 290 Demonstration of the running \lstinline{req} example, done using the \CFA list library\protect\footnotemark. 291 This example does the same job that Figure~\ref{fig:lst-issues-attach} shows three ways. 292 } 293 \end{figure} 294 \footnotetext{ 345 295 The \CFA list examples elide the \lstinline{P9_EMBEDDED} annotations that (TODO: xref P9E future work) proposes to obviate. 346 296 Thus, these examples illustrate a to-be state, free of what is to be historic clutter. 347 297 The elided portions are immaterial to the discussion and the examples work with the annotations provided. 348 The \CFA test suite (TODO:cite?) includes equivalent demonstrations, with the annotations included.} 349 These links have a nontrivial, user-specified location within the @req@ structure; 350 this convention encapsulates the implied pointer arithmetic safely. 351 352 \begin{figure} 353 \lstinputlisting[language=CFA, firstline=20, lastline=32]{lst-features-intro.run.cfa} 354 \caption[Multiple link directions in \CFA list library]{ 355 Demonstration of the running \lstinline{req} example, done using the \CFA list library. 356 This example does the same job that Figure~\ref{fig:lst-issues-attach} shows three ways. 357 } 358 \label{fig:lst-features-intro} 359 \end{figure} 360 361 \begin{figure} 362 \centering 363 \begin{tabular}{@{}ll@{}} 364 \begin{tabular}{@{}l@{}} 365 \lstinputlisting[language=CFA, firstline=20, lastline=25]{lst-features-multidir.run.cfa} \\ 298 The \CFA test suite (TODO:cite?) includes equivalent demonstrations, with the annotations included. 299 }. 300 301 My \CFA list library's version of the running @req@ example is in Figure~\ref{fig:lst-features-intro}. 302 Its link attachment is intrusive and the resulting memory layout is pure-stack, just as for the LQ version of Figure~\ref{fig:lst-issues-attach}-(a). 303 The framework-provided type @dlink(-)@ provides the links. 304 The user puts links into the @req@ structure by inline-inheriting (TODO: reference introduction) this type. 305 Which means: the type of the field is @dlink(req)@; the field is unnamed; a reference to a @req@ is implicitly convertible to @dlink@. 306 As these links have a nontrivial, user-specified location within the @req@ structure, this conversion also encapsulates the implied pointer arithmetic safely. 307 308 \begin{figure} 309 \label{fig:lst-features-multidir} 310 \lstinputlisting[language=CFA, firstline=20, lastline=25]{lst-features-multidir.run.cfa} 366 311 \lstinputlisting[language=CFA, firstline=40, lastline=67]{lst-features-multidir.run.cfa} 367 \end{tabular} 368 & 369 \lstinputlisting[language=C++, firstline=20, lastline=60]{lst-issues-multi-static.run.c} 370 \end{tabular} 371 372 \caption{ 312 \caption{ 373 313 Demonstration of multiple static link directions done in the \CFA list library. 374 314 This example does the same job as Figure~\ref{fig:lst-issues-multi-static}. 375 315 } 376 \label{fig:lst-features-multidir} 377 \end{figure} 378 379 Figure~\ref{fig:lst-features-multidir} shows how the \CFA library supports multi-static link directionality. 316 \end{figure} 317 318 The \CFA library supports multi-static link directionality. Figure~\ref{fig:lst-features-multidir} illustrates how. 380 319 The declaration of @req@ now has two inline-inheriting @dlink@ occurrences. 381 The first of these lines gives a type named @req.by_pri@ , @req@ inherits from it, andit inherits from @dlink@.382 The second line @req.by_rqr@ is similar to @req.by_pri@.320 The first of these lines gives a type named @req.by_pri@; @req@ inherits from it; it inherits from @dlink@. 321 The second line gives a similar @req.by_rqr@. 383 322 Thus, there is a diamond, non-virtual, inheritance from @req@ to @dlink@, with @by_pri@ and @by_rqr@ being the mid-level types. 384 323 Disambiguation occurs in the declarations of the list-head objects. 385 324 The type of the variable @reqs_pri_global@ is @dlist(req, req.by_pri)@, 386 325 meaning operations called on @reqs_pri_global@ are implicitly disambiguated. 387 In the example, the calls @insert_first(reqs_pri_global, ...)@ imply, ``here, we are working by priority.''326 In the example, the calls @insert_first(reqs_pri_global, ...)@ imply, ``here, we're working by priority.'' 388 327 389 328 The \CFA library also supports the common case, of single directionality, more naturally than LQ. 390 329 Figure~\ref{fig:lst-features-intro} shows a single-direction list done with no contrived name for the link direction, 391 where Figure~\ref{f :Intrusive}adds the unnecessary name, @x@.330 where Figure~\ref{fig:lst-issues-attach}-(a) adds the unnecessary name, @x@. 392 331 In \CFA, a user doing a single direction (Figure~\ref{fig:lst-features-intro}) 393 sets up a simple inheritance with @dlink@, and declares a list head to have the simpler type @dlist( ...)@.332 sets up a simple inheritance with @dlink@, and declares a list head to have the simpler type @dlist(-)@. 394 333 While a user doing multiple link directions (Figure~\ref{fig:lst-features-multidir}) 395 sets up a diamond inheritance with @dlink@, and declares a list head to have the more-informed type @dlist( ..., DIR)@.334 sets up a diamond inheritance with @dlink@, and declares a list head to have the more-informed type @dlist(-, DIR)@. 396 335 397 336 The \CFA library offers a type-system mediated integration with user code. … … 409 348 410 349 350 351 352 411 353 \subsection{Iteration} 412 354 -
doc/theses/mike_brooks_MMath/uw-ethesis.tex
r75d874a r0e16a2d 60 60 % For hyperlinked PDF, suitable for viewing on a computer, use this: 61 61 \documentclass[letterpaper,12pt,titlepage,oneside,final]{book} 62 \usepackage{times}63 62 \usepackage[T1]{fontenc} % Latin-1 => 256-bit characters, => | not dash, <> not Spanish question marks 64 63 … … 88 87 \usepackage{comment} % Removes large sections of the document. 89 88 \usepackage{tabularx} 90 \usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt,font=normalsize]{subfig} 91 \renewcommand\thesubfigure{(\alph{subfigure})} 89 \usepackage{subfigure} 92 90 93 91 \usepackage{algorithm} 94 92 \usepackage{algpseudocode} 93 94 \usepackage{pbox} 95 95 96 96 % Hyperlinks make it very easy to navigate an electronic document. … … 117 117 citecolor=blue, % color of links to bibliography 118 118 filecolor=magenta, % color of file links 119 urlcolor=blue, % color of external links 120 breaklinks=true 119 urlcolor=blue % color of external links 121 120 } 122 121 \ifthenelse{\boolean{PrintVersion}}{ % for improved print quality, change some hyperref options … … 181 180 \CFAStyle % CFA code-style 182 181 \lstset{language=CFA} % default language 183 \lstset{basicstyle=\linespread{0.9}\ sf} % CFA typewriter font182 \lstset{basicstyle=\linespread{0.9}\tt} % CFA typewriter font 184 183 \lstset{inputpath={programs}} 185 184 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 186 185 187 \newcommand{\uCpp}{$\mu$\CC} 186 187 \newcommand{\uCpp}{$\mu${C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}}} 188 188 189 189 %====================================================================== -
libcfa/src/bits/random.hfa
r75d874a r0e16a2d 10 10 // Created On : Fri Jan 14 07:18:11 2022 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 20 21:45:24202313 // Update Count : 18 612 // Last Modified On : Mon Mar 20 10:01:40 2023 13 // Update Count : 180 14 14 // 15 15 … … 131 131 #ifdef __cforall // don't include in C code (invoke.h) 132 132 133 // Splitmix64 133 134 // https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64 134 // 135 // Splitmix64 is not recommended for demanding random number requirements, but is often used to calculate initial states 136 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it). 137 // Also https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64. 135 // Splitmix64 is not recommended for demanding random number requirements, 136 // but is often used to calculate initial states for other more complex 137 // pseudo-random number generators. 138 138 static inline uint64_t splitmix64( uint64_t & state ) { 139 139 state += 0x9e3779b97f4a7c15; … … 149 149 } // splitmix64_set_seed 150 150 151 // Splitmix32 151 152 // https://github.com/bryc/code/blob/master/jshash/PRNGs.md#splitmix32 152 // 153 // Splitmix32 is not recommended for demanding random number requirements, but is often used to calculate initial states154 // for other more complex pseudo-random number generators (see https://prng.di.unimi.it).155 153 // Splitmix32 is not recommended for demanding random number requirements, 154 // but is often used to calculate initial states for other more complex 155 // pseudo-random number generators. 156 // SplitMix32 is a 32 bit variant of Splitmix64 156 157 static inline uint32_t splitmix32( uint32_t & state ) { 157 158 state += 0x9e3779b9; … … 168 169 169 170 #ifdef __SIZEOF_INT128__ 170 //-------------------------------------------------- 171 static inline uint64_t lehmer64( __uint128_t & state ) { 172 __uint128_t ret = state; 173 state *= 0x_da94_2042_e4dd_58b5; 174 return ret >> 64; 175 } // lehmer64 176 177 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 178 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed. 179 state = splitmix64( seed ); // prime 180 } // lehmer64_set_seed 181 182 //-------------------------------------------------- 183 static inline uint64_t wyhash64( uint64_t & state ) { 184 uint64_t ret = state; 185 state += 0x_60be_e2be_e120_fc15; 186 __uint128_t tmp; 187 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 188 uint64_t m1 = (tmp >> 64) ^ tmp; 189 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 190 uint64_t m2 = (tmp >> 64) ^ tmp; 191 return m2; 192 } // wyhash64 193 194 static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) { 195 state = splitmix64( seed ); // prime 196 } // wyhash64_set_seed 171 //-------------------------------------------------- 172 static inline uint64_t lehmer64( __uint128_t & state ) { 173 __uint128_t ret = state; 174 state *= 0x_da94_2042_e4dd_58b5; 175 return ret >> 64; 176 } // lehmer64 177 178 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 179 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed. 180 state = seed; 181 lehmer64( state ); // prime 182 } // lehmer64_set_seed 183 184 //-------------------------------------------------- 185 static inline uint64_t wyhash64( uint64_t & state ) { 186 uint64_t ret = state; 187 state += 0x_60be_e2be_e120_fc15; 188 __uint128_t tmp; 189 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 190 uint64_t m1 = (tmp >> 64) ^ tmp; 191 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 192 uint64_t m2 = (tmp >> 64) ^ tmp; 193 return m2; 194 } // wyhash64 197 195 #endif // __SIZEOF_INT128__ 198 196 … … 229 227 230 228 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 231 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 232 uint64_t seed1 = splitmix64( seed ); // prime 229 // these are done explicitly in this order to attain repeatable seeding. 230 // do not call splitmix64 directly in the state init since order of argument evaluation 231 // may not be consistent leading to irreproducible seeding 232 uint64_t seed1 = splitmix64( seed ); 233 233 uint64_t seed2 = splitmix64( seed ); 234 234 uint64_t seed3 = splitmix64( seed ); 235 235 uint64_t seed4 = splitmix64( seed ); 236 236 state = (xoshiro256pp_t){ seed1, seed2, seed3, seed4 }; 237 xoshiro256pp( state ); // prime 237 238 } // xoshiro256pp_set_seed 238 239 … … 268 269 269 270 static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) { 270 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 271 uint32_t seed1 = splitmix32( seed ); // prime 271 // these are done explicitly in this order to attain repeatable seeding. 272 // do not call splitmix32 directly in the state init since order of argument evaluation 273 // may not be consistent leading to irreproducible seeding 274 uint32_t seed1 = splitmix32( seed ); 272 275 uint32_t seed2 = splitmix32( seed ); 273 276 uint32_t seed3 = splitmix32( seed ); 274 277 uint32_t seed4 = splitmix32( seed ); 275 278 state = (xoshiro128pp_t){ seed1, seed2, seed3, seed4 }; 279 xoshiro128pp( state ); // prime 276 280 } // xoshiro128pp_set_seed 277 281 … … 286 290 287 291 static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) { 288 state = splitmix64( seed ); // prime 292 state = seed; 293 xorshift_13_7_17( state ); // prime 289 294 } // xorshift_13_7_17_set_seed 290 295 … … 303 308 304 309 static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) { 305 state = splitmix32( seed ); // prime 310 state = seed; 311 xorshift_6_21_7( state ); // prime 306 312 } // xorshift_6_21_7_set_seed 307 313 … … 317 323 318 324 static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) { 319 state = splitmix64( seed ); // prime 325 state = seed; 326 xorshift_12_25_27( state ); // prime 320 327 } // xorshift_12_25_27_set_seed 321 328 … … 338 345 339 346 static inline void kiss_64_set_seed( kiss_64_t & rs, uint64_t seed ) with(rs) { 340 z = 1; w = 1; jsr = 4; jcong = splitmix64( seed ); // prime 347 z = 1; w = 1; jsr = 4; jcong = seed; 348 kiss_64( rs ); // prime 341 349 } // kiss_64_set_seed 342 350 … … 366 374 367 375 static inline void xorwow_set_seed( xorwow_t & rs, uint32_t seed ) { 368 // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined. 369 uint32_t seed1 = splitmix32( seed ); // prime 376 // these are done explicitly in this order to attain repeatable seeding. 377 // do not call splitmix32 directly in the state init since order of argument evaluation 378 // may not be consistent leading to irreproducible seeding 379 uint32_t seed1 = splitmix32( seed ); 370 380 uint32_t seed2 = splitmix32( seed ); 371 381 uint32_t seed3 = splitmix32( seed ); 372 382 uint32_t seed4 = splitmix32( seed ); 373 383 rs = (xorwow_t){ seed1, seed2, seed3, seed4, 0 }; 384 xorwow( rs ); // prime 374 385 } // xorwow_set_seed 375 386 … … 377 388 // Used in __tls_rand_fwd 378 389 #define M (1_l64u << 48_l64u) 379 #define A (25 _214_903_917_l64u)380 #define AI (18 _446_708_753_438_544_741_l64u)390 #define A (25214903917_l64u) 391 #define AI (18446708753438544741_l64u) 381 392 #define C (11_l64u) 382 393 #define D (16_l64u) -
libcfa/src/concurrency/channel.hfa
r75d874a r0e16a2d 2 2 3 3 #include <locks.hfa> 4 #include <list.hfa> 5 6 #define __COOP_CHANNEL 4 5 struct no_reacq_lock { 6 inline exp_backoff_then_block_lock; 7 }; 8 9 // have to override these by hand to get around plan 9 inheritance bug where resolver can't find the appropriate routine to call 10 static inline void ?{}( no_reacq_lock & this ) { ((exp_backoff_then_block_lock &)this){}; } 11 static inline bool try_lock(no_reacq_lock & this) { return try_lock(((exp_backoff_then_block_lock &)this)); } 12 static inline void lock(no_reacq_lock & this) { lock(((exp_backoff_then_block_lock &)this)); } 13 static inline void unlock(no_reacq_lock & this) { unlock(((exp_backoff_then_block_lock &)this)); } 14 static inline void on_notify(no_reacq_lock & this, struct thread$ * t ) { on_notify(((exp_backoff_then_block_lock &)this), t); } 15 static inline size_t on_wait(no_reacq_lock & this) { return on_wait(((exp_backoff_then_block_lock &)this)); } 16 // override wakeup so that we don't reacquire the lock if using a condvar 17 static inline void on_wakeup( no_reacq_lock & this, size_t recursion ) {} 18 19 #define __PREVENTION_CHANNEL 7 20 #ifdef __PREVENTION_CHANNEL 8 21 forall( T ) { 9 22 struct channel { 10 size_t size, count, front, back; 23 size_t size; 24 size_t front, back, count; 11 25 T * buffer; 12 26 thread$ * chair; … … 73 87 return; 74 88 } 75 insert_( chan, elem );89 else insert_( chan, elem ); 76 90 77 91 unlock( mutex_lock ); … … 96 110 97 111 // wait if buffer is empty, work will be completed by someone else 98 if ( count == 0 ) { 112 if ( count == 0 ) { 99 113 chair = active_thread(); 100 114 chair_elem = &retval; … … 107 121 memcpy((void *)&retval, (void *)&buffer[front], sizeof(T)); 108 122 count -= 1; 109 front++; 110 if ( front == size ) front = 0; 123 front = (front + 1) % size; 111 124 112 125 if ( chair != 0p ) { … … 129 142 130 143 #ifdef __COOP_CHANNEL 131 132 // link field used for threads waiting on channel133 struct wait_link {134 // used to put wait_link on a dl queue135 inline dlink(wait_link);136 137 // waiting thread138 struct thread$ * t;139 140 // shadow field141 void * elem;142 };143 P9_EMBEDDED( wait_link, dlink(wait_link) )144 145 static inline void ?{}( wait_link & this, thread$ * t, void * elem ) {146 this.t = t;147 this.elem = elem;148 }149 150 144 forall( T ) { 151 152 145 struct channel { 153 146 size_t size; 154 147 size_t front, back, count; 155 148 T * buffer; 156 dlist( wait_link ) prods, cons;157 exp_backoff_then_block_lock mutex_lock;149 fast_cond_var( no_reacq_lock ) prods, cons; 150 no_reacq_lock mutex_lock; 158 151 }; 159 152 … … 171 164 static inline size_t get_count( channel(T) & chan ) with(chan) { return count; } 172 165 static inline size_t get_size( channel(T) & chan ) with(chan) { return size; } 173 static inline bool has_waiters( channel(T) & chan ) with(chan) { return ! cons`isEmpty || !prods`isEmpty; }174 static inline bool has_waiting_consumers( channel(T) & chan ) with(chan) { return ! cons`isEmpty; }175 static inline bool has_waiting_producers( channel(T) & chan ) with(chan) { return ! prods`isEmpty; }166 static inline bool has_waiters( channel(T) & chan ) with(chan) { return !empty( cons ) || !empty( prods ); } 167 static inline bool has_waiting_consumers( channel(T) & chan ) with(chan) { return !empty( cons ); } 168 static inline bool has_waiting_producers( channel(T) & chan ) with(chan) { return !empty( prods ); } 176 169 177 170 static inline void insert_( channel(T) & chan, T & elem ) with(chan) { … … 182 175 } 183 176 184 static inline void wake_one( dlist( wait_link ) & queue ) {185 wait_link & popped = try_pop_front( queue );186 unpark( popped.t );187 }188 189 static inline void block( dlist( wait_link ) & queue, void * elem_ptr, exp_backoff_then_block_lock & lock ) {190 wait_link w{ active_thread(), elem_ptr };191 insert_last( queue, w );192 unlock( lock );193 park();194 }195 177 196 178 static inline void insert( channel(T) & chan, T elem ) with(chan) { … … 198 180 199 181 // have to check for the zero size channel case 200 if ( size == 0 && ! cons`isEmpty) {201 memcpy( cons`first.elem, (void *)&elem, sizeof(T));202 wake_one( cons );182 if ( size == 0 && !empty( cons ) ) { 183 memcpy((void *)front( cons ), (void *)&elem, sizeof(T)); 184 notify_one( cons ); 203 185 unlock( mutex_lock ); 204 186 return; … … 206 188 207 189 // wait if buffer is full, work will be completed by someone else 208 if ( count == size ) { 209 block( prods, &elem, mutex_lock);190 if ( count == size ) { 191 wait( prods, mutex_lock, (uintptr_t)&elem ); 210 192 return; 211 193 } // if 212 194 213 if ( count == 0 && ! cons`isEmpty ) {214 memcpy(cons`first.elem, (void *)&elem, sizeof(T));// do waiting consumer work215 wake_one( cons );216 }else insert_( chan, elem );195 if ( count == 0 && !empty( cons ) ) 196 // do waiting consumer work 197 memcpy((void *)front( cons ), (void *)&elem, sizeof(T)); 198 else insert_( chan, elem ); 217 199 200 notify_one( cons ); 218 201 unlock( mutex_lock ); 219 202 } … … 224 207 225 208 // have to check for the zero size channel case 226 if ( size == 0 && ! prods`isEmpty) {227 memcpy((void *)&retval, (void *) prods`first.elem, sizeof(T));228 wake_one( prods );209 if ( size == 0 && !empty( prods ) ) { 210 memcpy((void *)&retval, (void *)front( prods ), sizeof(T)); 211 notify_one( prods ); 229 212 unlock( mutex_lock ); 230 213 return retval; … … 232 215 233 216 // wait if buffer is empty, work will be completed by someone else 234 if (count == 0) { 235 block( cons, &retval, mutex_lock);217 if (count == 0) { 218 wait( cons, mutex_lock, (uintptr_t)&retval ); 236 219 return retval; 237 220 } … … 242 225 front = (front + 1) % size; 243 226 244 if (count == size - 1 && !prods`isEmpty ) { 245 insert_( chan, *(T *)prods`first.elem ); // do waiting producer work 246 wake_one( prods ); 247 } 248 227 if (count == size - 1 && !empty( prods ) ) 228 insert_( chan, *((T *)front( prods )) ); // do waiting producer work 229 230 notify_one( prods ); 249 231 unlock( mutex_lock ); 250 232 return retval; 251 233 } 234 252 235 } // forall( T ) 253 236 #endif -
libcfa/src/concurrency/io.cfa
r75d874a r0e16a2d 295 295 // make sure the target hasn't stopped existing since last time 296 296 HELP: if(target < ctxs_count) { 297 // calculate it's age and how young it could be before we give up on helping297 // calculate it's age and how young it could be before we give ip on helping 298 298 const __readyQ_avg_t cutoff = calc_cutoff(ctsc, ctx->cq.id, ctxs_count, io.data, io.tscs, __shard_factor.io, false); 299 299 const __readyQ_avg_t age = moving_average(ctsc, io.tscs[target].t.tv, io.tscs[target].t.ma, false); -
libcfa/src/concurrency/io/call.cfa.in
r75d874a r0e16a2d 89 89 #if defined(CFA_HAVE_PREADV2) 90 90 struct iovec; 91 extern ssize_t preadv2 (int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags);91 extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); 92 92 #endif 93 93 #if defined(CFA_HAVE_PWRITEV2) 94 94 struct iovec; 95 extern ssize_t pwritev2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags);95 extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags); 96 96 #endif 97 97 … … 108 108 struct msghdr; 109 109 struct sockaddr; 110 extern ssize_t sendmsg(int sockfd, const struct msghdr * msg, int flags);111 extern ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags);112 extern ssize_t send(int sockfd, const void * buf, size_t len, int flags);113 extern ssize_t recv(int sockfd, void * buf, size_t len, int flags);110 extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); 111 extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); 112 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags); 113 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags); 114 114 115 115 extern int fallocate(int fd, int mode, off_t offset, off_t len); 116 116 extern int posix_fadvise(int fd, off_t offset, off_t len, int advice); 117 extern int madvise(void * addr, size_t length, int advice);118 119 extern int openat(int dirfd, const char * pathname, int flags, mode_t mode);117 extern int madvise(void *addr, size_t length, int advice); 118 119 extern int openat(int dirfd, const char *pathname, int flags, mode_t mode); 120 120 extern int close(int fd); 121 121 122 extern ssize_t read (int fd, void * buf, size_t count);122 extern ssize_t read (int fd, void *buf, size_t count); 123 123 124 124 struct epoll_event; 125 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event * event);126 127 extern ssize_t splice(int fd_in, __off64_t * off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags);125 extern int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 126 127 extern ssize_t splice(int fd_in, __off64_t *off_in, int fd_out, __off64_t *off_out, size_t len, unsigned int flags); 128 128 extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags); 129 129 } … … 224 224 calls = [ 225 225 # CFA_HAVE_IORING_OP_READV 226 Call('READV', 'ssize_t preadv2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags)', {226 Call('READV', 'ssize_t preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', { 227 227 'fd' : 'fd', 228 'addr': '(typeof(sqe->addr))iov', 228 'off' : 'offset', 229 'addr': '(uintptr_t)iov', 229 230 'len' : 'iovcnt', 230 'off' : 'offset',231 'rw_flags' : 'flags'232 231 }, define = 'CFA_HAVE_PREADV2'), 233 232 # CFA_HAVE_IORING_OP_WRITEV 234 Call('WRITEV', 'ssize_t pwritev2(int fd, const struct iovec * iov, int iovcnt, off_t offset, int flags)', {233 Call('WRITEV', 'ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags)', { 235 234 'fd' : 'fd', 236 'addr': '(typeof(sqe->addr))iov',237 'len' : 'iovcnt',238 235 'off' : 'offset', 239 'rw_flags' : 'flags' 236 'addr': '(uintptr_t)iov', 237 'len' : 'iovcnt' 240 238 }, define = 'CFA_HAVE_PWRITEV2'), 241 239 # CFA_HAVE_IORING_OP_FSYNC … … 244 242 }), 245 243 # CFA_HAVE_IORING_OP_EPOLL_CTL 246 Call('EPOLL_CTL', 'int epoll_ctl(int epfd, int op, int fd, struct epoll_event * event)', {244 Call('EPOLL_CTL', 'int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)', { 247 245 'fd': 'epfd', 246 'addr': 'fd', 248 247 'len': 'op', 249 'addr': 'fd', 250 'off': '(typeof(sqe->off))event' 248 'off': '(uintptr_t)event' 251 249 }), 252 250 # CFA_HAVE_IORING_OP_SYNC_FILE_RANGE … … 258 256 }), 259 257 # CFA_HAVE_IORING_OP_SENDMSG 260 Call('SENDMSG', 'ssize_t sendmsg(int sockfd, const struct msghdr * msg, int flags)', {261 'fd': 'sockfd', 262 'addr': '( typeof(sqe->addr))(struct msghdr *)msg',258 Call('SENDMSG', 'ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)', { 259 'fd': 'sockfd', 260 'addr': '(uintptr_t)(struct msghdr *)msg', 263 261 'len': '1', 264 262 'msg_flags': 'flags' 265 263 }), 266 264 # CFA_HAVE_IORING_OP_RECVMSG 267 Call('RECVMSG', 'ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags)', {268 'fd': 'sockfd', 269 'addr': '( typeof(sqe->addr))(struct msghdr *)msg',265 Call('RECVMSG', 'ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)', { 266 'fd': 'sockfd', 267 'addr': '(uintptr_t)(struct msghdr *)msg', 270 268 'len': '1', 271 269 'msg_flags': 'flags' 272 270 }), 273 271 # CFA_HAVE_IORING_OP_SEND 274 Call('SEND', 'ssize_t send(int sockfd, const void * buf, size_t len, int flags)', {275 'fd': 'sockfd', 276 'addr': '( typeof(sqe->addr))buf',272 Call('SEND', 'ssize_t send(int sockfd, const void *buf, size_t len, int flags)', { 273 'fd': 'sockfd', 274 'addr': '(uintptr_t)buf', 277 275 'len': 'len', 278 276 'msg_flags': 'flags' 279 277 }), 280 278 # CFA_HAVE_IORING_OP_RECV 281 Call('RECV', 'ssize_t recv(int sockfd, void * buf, size_t len, int flags)', {282 'fd': 'sockfd', 283 'addr': '( typeof(sqe->addr))buf',279 Call('RECV', 'ssize_t recv(int sockfd, void *buf, size_t len, int flags)', { 280 'fd': 'sockfd', 281 'addr': '(uintptr_t)buf', 284 282 'len': 'len', 285 283 'msg_flags': 'flags' … … 288 286 Call('ACCEPT', 'int accept4(int sockfd, __SOCKADDR_ARG addr, socklen_t * restrict addrlen, int flags)', { 289 287 'fd': 'sockfd', 290 'addr': '( typeof(sqe->addr))&addr',291 'addr2': '( typeof(sqe->addr2))addrlen',288 'addr': '(uintptr_t)&addr', 289 'addr2': '(uintptr_t)addrlen', 292 290 'accept_flags': 'flags' 293 291 }), … … 295 293 Call('CONNECT', 'int connect(int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)', { 296 294 'fd': 'sockfd', 297 'addr': '( typeof(sqe->addr))&addr',295 'addr': '(uintptr_t)&addr', 298 296 'off': 'addrlen' 299 297 }), … … 301 299 Call('FALLOCATE', 'int fallocate(int fd, int mode, off_t offset, off_t len)', { 302 300 'fd': 'fd', 301 'addr': '(uintptr_t)len', 303 302 'len': 'mode', 304 'off': 'offset', 305 'addr': 'len' 303 'off': 'offset' 306 304 }), 307 305 # CFA_HAVE_IORING_OP_FADVISE … … 313 311 }), 314 312 # CFA_HAVE_IORING_OP_MADVISE 315 Call('MADVISE', 'int madvise(void * addr, size_t length, int advice)', {316 'addr': '( typeof(sqe->addr))addr',313 Call('MADVISE', 'int madvise(void *addr, size_t length, int advice)', { 314 'addr': '(uintptr_t)addr', 317 315 'len': 'length', 318 316 'fadvise_advice': 'advice' 319 317 }), 320 318 # CFA_HAVE_IORING_OP_OPENAT 321 Call('OPENAT', 'int openat(int dirfd, const char * pathname, int flags, mode_t mode)', {319 Call('OPENAT', 'int openat(int dirfd, const char *pathname, int flags, mode_t mode)', { 322 320 'fd': 'dirfd', 323 'addr': '( typeof(sqe->addr))pathname',324 ' open_flags': 'flags;',325 ' len': 'mode'321 'addr': '(uintptr_t)pathname', 322 'len': 'mode', 323 'open_flags': 'flags;' 326 324 }), 327 325 # CFA_HAVE_IORING_OP_OPENAT2 328 Call('OPENAT2', 'int openat2(int dirfd, const char * pathname, struct open_how * how, size_t size)', {326 Call('OPENAT2', 'int openat2(int dirfd, const char *pathname, struct open_how * how, size_t size)', { 329 327 'fd': 'dirfd', 330 'addr': ' (typeof(sqe->addr))pathname',331 ' off': '(typeof(sqe->off))how',332 ' len': 'sizeof(*how)'328 'addr': 'pathname', 329 'len': 'sizeof(*how)', 330 'off': '(uintptr_t)how', 333 331 }, define = 'CFA_HAVE_OPENAT2'), 334 332 # CFA_HAVE_IORING_OP_CLOSE … … 337 335 }), 338 336 # CFA_HAVE_IORING_OP_STATX 339 Call('STATX', 'int statx(int dirfd, const char * pathname, int flags, unsigned int mask, struct statx *statxbuf)', {337 Call('STATX', 'int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf)', { 340 338 'fd': 'dirfd', 341 ' addr': '(typeof(sqe->addr))pathname',342 ' statx_flags': 'flags',339 'off': '(uintptr_t)statxbuf', 340 'addr': 'pathname', 343 341 'len': 'mask', 344 ' off': '(typeof(sqe->off))statxbuf'342 'statx_flags': 'flags' 345 343 }, define = 'CFA_HAVE_STATX'), 346 344 # CFA_HAVE_IORING_OP_READ 347 345 Call('READ', 'ssize_t read(int fd, void * buf, size_t count)', { 348 346 'fd': 'fd', 349 'addr': '( typeof(sqe->addr))buf',347 'addr': '(uintptr_t)buf', 350 348 'len': 'count' 351 349 }), … … 353 351 Call('WRITE', 'ssize_t write(int fd, void * buf, size_t count)', { 354 352 'fd': 'fd', 355 'addr': '( typeof(sqe->addr))buf',353 'addr': '(uintptr_t)buf', 356 354 'len': 'count' 357 355 }), 358 356 # CFA_HAVE_IORING_OP_SPLICE 359 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)', {357 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)', { 360 358 'splice_fd_in': 'fd_in', 361 'splice_off_in': 'off_in ? ( typeof(sqe->splice_off_in))*off_in : (typeof(sqe->splice_off_in))-1',359 'splice_off_in': 'off_in ? (__u64)*off_in : (__u64)-1', 362 360 'fd': 'fd_out', 363 'off': 'off_out ? ( typeof(sqe->off))*off_out : (typeof(sqe->off))-1',361 'off': 'off_out ? (__u64)*off_out : (__u64)-1', 364 362 'len': 'len', 365 363 'splice_flags': 'flags' -
libcfa/src/concurrency/locks.hfa
r75d874a r0e16a2d 253 253 static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); } 254 254 255 255 256 //----------------------------------------------------------------------------- 256 257 // Exponential backoff then block lock … … 271 272 this.lock_value = 0; 272 273 } 274 static inline void ^?{}( exp_backoff_then_block_lock & this ) {} 275 // static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 276 // static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void; 273 277 274 278 static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) { 275 return __atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); 279 if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { 280 return true; 281 } 282 return false; 276 283 } 277 284 … … 279 286 280 287 static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) { 281 return !__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE); 288 if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) { 289 return true; 290 } 291 return false; 282 292 } 283 293 284 294 static inline bool block(exp_backoff_then_block_lock & this) with(this) { 285 lock( spinlock __cfaabi_dbg_ctx2 ); 286 if (__atomic_load_n( &lock_value, __ATOMIC_SEQ_CST)!= 2) {287 unlock( spinlock );288 return true;289 }290 insert_last( blocked_threads, *active_thread() );291 unlock( spinlock );295 lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC) 296 if (lock_value != 2) { 297 unlock( spinlock ); 298 return true; 299 } 300 insert_last( blocked_threads, *active_thread() ); 301 unlock( spinlock ); 292 302 park( ); 293 303 return true; … … 297 307 size_t compare_val = 0; 298 308 int spin = 4; 299 300 309 // linear backoff 301 310 for( ;; ) { … … 315 324 static inline void unlock(exp_backoff_then_block_lock & this) with(this) { 316 325 if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return; 317 lock( spinlock __cfaabi_dbg_ctx2 );318 thread$ * t = &try_pop_front( blocked_threads );319 unlock( spinlock );320 unpark( t );326 lock( spinlock __cfaabi_dbg_ctx2 ); 327 thread$ * t = &try_pop_front( blocked_threads ); 328 unlock( spinlock ); 329 unpark( t ); 321 330 } 322 331 -
src/AST/Print.cpp
r75d874a r0e16a2d 369 369 --indent; 370 370 } 371 }372 373 if ( ! node->withExprs.empty() ) {374 // Not with a clause, but the 'with clause'.375 ++indent;376 os << " with clause" << endl << indent;377 printAll( node->withExprs );378 --indent;379 371 } 380 372 -
src/Common/module.mk
r75d874a r0e16a2d 20 20 Common/CodeLocationTools.hpp \ 21 21 Common/CodeLocationTools.cpp \ 22 Common/Debug.h \ 22 23 Common/DeclStats.hpp \ 23 24 Common/DeclStats.cpp \ -
src/Common/utility.h
r75d874a r0e16a2d 190 190 } 191 191 192 template< typename... Params > 193 void warn( const Params & ... params ) { 194 std::cerr << "Warning: "; 195 toString_single( std::cerr, params... ); 196 std::cerr << std::endl; 197 } 198 192 199 // determines if pref is a prefix of str 193 200 static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) { -
src/InitTweak/FixInit.cc
r75d874a r0e16a2d 1233 1233 } 1234 1234 1235 template< typename Visitor, typename... Params > 1236 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1237 SemanticErrorException err( loc, toString( params... ) ); 1238 v.errors.append( err ); 1239 } 1240 1235 1241 template< typename... Params > 1236 1242 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1237 SemanticErrorException err( loc, toString( params... ) ); 1238 errors.append( err ); 1243 // toggle warnings vs. errors here. 1244 // warn( params... ); 1245 error( *this, loc, params... ); 1239 1246 } 1240 1247 -
src/InitTweak/FixInitNew.cpp
r75d874a r0e16a2d 1303 1303 } 1304 1304 1305 template< typename Visitor, typename... Params > 1306 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1307 SemanticErrorException err( loc, toString( params... ) ); 1308 v.errors.append( err ); 1309 } 1310 1305 1311 template< typename... Params > 1306 1312 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1307 SemanticErrorException err( loc, toString( params... ) ); 1308 errors.append( err ); 1313 // toggle warnings vs. errors here. 1314 // warn( params... ); 1315 error( *this, loc, params... ); 1309 1316 } 1310 1317 -
src/Parser/parser.yy
r75d874a r0e16a2d 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 22 21:26:01202313 // Update Count : 600212 // Last Modified On : Tue Mar 14 09:37:58 2023 13 // Update Count : 5990 14 14 // 15 15 … … 270 270 SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n" 271 271 "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) ); 272 } // IdentifierBeforeType273 274 static bool TypedefForall( DeclarationNode * decl ) {275 if ( decl->type->forall || (decl->type->kind == TypeData::Aggregate && decl->type->aggregate.params) ) {276 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." );277 return true;278 } // if279 return false;280 272 } // IdentifierBeforeType 281 273 … … 504 496 %type<decl> typedef_name typedef_declaration typedef_expression 505 497 506 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function 507 %type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr 498 %type<decl> variable_type_redeclarator type_ptr type_array type_function 508 499 509 500 %type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function … … 1966 1957 TYPEDEF type_specifier declarator 1967 1958 { 1959 // if type_specifier is an anon aggregate => name 1968 1960 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 1969 if ( TypedefForall( $2 ) ) $$ = nullptr; 1970 else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1961 $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1971 1962 } 1972 1963 | typedef_declaration pop ',' push declarator … … 1978 1969 { 1979 1970 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" ); 1980 if ( TypedefForall( $1 ) ) $$ = nullptr; 1981 else $$ = $4->addQualifiers( $1 )->addType( $3 )->addTypedef(); 1971 $$ = $4->addQualifiers( $1 )->addType( $3 )->addTypedef(); 1982 1972 } 1983 1973 | type_specifier TYPEDEF declarator 1984 1974 { 1985 1975 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" ); 1986 if ( TypedefForall( $1 ) ) $$ = nullptr; 1987 else $$ = $3->addType( $1 )->addTypedef(); 1976 $$ = $3->addType( $1 )->addTypedef(); 1988 1977 } 1989 1978 | type_specifier TYPEDEF type_qualifier_list declarator 1990 1979 { 1991 1980 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" ); 1992 if ( TypedefForall( $3 ) ) $$ = nullptr; 1993 else $$ = $4->addQualifiers( $1 )->addType( $1 )->addTypedef(); 1981 $$ = $4->addQualifiers( $1 )->addType( $1 )->addTypedef(); 1994 1982 } 1995 1983 ; … … 2028 2016 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 2029 2017 // storage-class 2030 variable_declarator asm_name_opt initializer_opt2018 declarator asm_name_opt initializer_opt 2031 2019 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2032 | variable_type_redeclarator asm_name_opt initializer_opt2033 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }2034 2035 | general_function_declarator asm_name_opt2036 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }2037 | general_function_declarator asm_name_opt '=' VOID2038 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }2039 2040 2020 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2041 2021 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2042 ;2043 2044 general_function_declarator:2045 function_type_redeclarator2046 | function_declarator2047 2022 ; 2048 2023 … … 2568 2543 // A semantic check is required to ensure bit_subrange only appears on integral types. 2569 2544 { $$ = $1->addBitfield( $2 ); } 2570 | function_type_redeclarator bit_subrange_size_opt2571 // A semantic check is required to ensure bit_subrange only appears on integral types.2572 { $$ = $1->addBitfield( $2 ); }2573 2545 ; 2574 2546 … … 3223 3195 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3224 3196 } 3225 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement3197 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement 3226 3198 { 3227 3199 rebindForall( $1, $2 ); … … 3259 3231 | variable_type_redeclarator 3260 3232 | function_declarator 3261 | function_type_redeclarator3262 3233 ; 3263 3234 … … 3510 3481 ; 3511 3482 3512 // This pattern parses a declaration for a variable that redefines a type name, e.g.:3483 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.: 3513 3484 // 3514 3485 // typedef int foo; … … 3516 3487 // int foo; // redefine typedef name in new scope 3517 3488 // } 3489 // 3490 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 3491 // and functions versus pointers to arrays and functions. 3518 3492 3519 3493 paren_type: … … 3530 3504 paren_type attribute_list_opt 3531 3505 { $$ = $1->addQualifiers( $2 ); } 3532 | variable_type_ptr3533 | variable_type_array attribute_list_opt3506 | type_ptr 3507 | type_array attribute_list_opt 3534 3508 { $$ = $1->addQualifiers( $2 ); } 3535 | variable_type_function attribute_list_opt3509 | type_function attribute_list_opt 3536 3510 { $$ = $1->addQualifiers( $2 ); } 3537 3511 ; 3538 3512 3539 variable_type_ptr:3513 type_ptr: 3540 3514 ptrref_operator variable_type_redeclarator 3541 3515 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3542 3516 | ptrref_operator type_qualifier_list variable_type_redeclarator 3543 3517 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3544 | '(' variable_type_ptr ')' attribute_list_opt// redundant parenthesis3518 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3545 3519 { $$ = $2->addQualifiers( $4 ); } 3546 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis3520 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3547 3521 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3548 3522 ; 3549 3523 3550 variable_type_array:3524 type_array: 3551 3525 paren_type array_dimension 3552 3526 { $$ = $1->addArray( $2 ); } 3553 | '(' variable_type_ptr ')' array_dimension3527 | '(' type_ptr ')' array_dimension 3554 3528 { $$ = $2->addArray( $4 ); } 3555 | '(' attribute_list variable_type_ptr ')' array_dimension3529 | '(' attribute_list type_ptr ')' array_dimension 3556 3530 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3557 | '(' variable_type_array ')' multi_array_dimension// redundant parenthesis3531 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3558 3532 { $$ = $2->addArray( $4 ); } 3559 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis3533 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3560 3534 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3561 | '(' variable_type_array ')'// redundant parenthesis3535 | '(' type_array ')' // redundant parenthesis 3562 3536 { $$ = $2; } 3563 | '(' attribute_list variable_type_array ')'// redundant parenthesis3537 | '(' attribute_list type_array ')' // redundant parenthesis 3564 3538 { $$ = $3->addQualifiers( $2 ); } 3565 3539 ; 3566 3540 3567 variable_type_function: 3568 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3569 { $$ = $2->addParamList( $6 ); } 3570 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3571 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3572 | '(' variable_type_function ')' // redundant parenthesis 3573 { $$ = $2; } 3574 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3575 { $$ = $3->addQualifiers( $2 ); } 3576 ; 3577 3578 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3579 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3580 // arrays and functions. 3581 3582 function_type_redeclarator: 3583 function_type_no_ptr attribute_list_opt 3584 { $$ = $1->addQualifiers( $2 ); } 3585 | function_type_ptr 3586 | function_type_array attribute_list_opt 3587 { $$ = $1->addQualifiers( $2 ); } 3588 ; 3589 3590 function_type_no_ptr: 3541 type_function: 3591 3542 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3592 3543 { $$ = $1->addParamList( $4 ); } 3593 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3544 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3594 3545 { $$ = $2->addParamList( $6 ); } 3595 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3546 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3596 3547 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3597 | '(' function_type_no_ptr ')'// redundant parenthesis3548 | '(' type_function ')' // redundant parenthesis 3598 3549 { $$ = $2; } 3599 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3600 { $$ = $3->addQualifiers( $2 ); } 3601 ; 3602 3603 function_type_ptr: 3604 ptrref_operator function_type_redeclarator 3605 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3606 | ptrref_operator type_qualifier_list function_type_redeclarator 3607 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3608 | '(' function_type_ptr ')' attribute_list_opt 3609 { $$ = $2->addQualifiers( $4 ); } 3610 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3611 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3612 ; 3613 3614 function_type_array: 3615 '(' function_type_ptr ')' array_dimension 3616 { $$ = $2->addArray( $4 ); } 3617 | '(' attribute_list function_type_ptr ')' array_dimension 3618 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3619 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3620 { $$ = $2->addArray( $4 ); } 3621 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3622 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3623 | '(' function_type_array ')' // redundant parenthesis 3624 { $$ = $2; } 3625 | '(' attribute_list function_type_array ')' // redundant parenthesis 3550 | '(' attribute_list type_function ')' // redundant parenthesis 3626 3551 { $$ = $3->addQualifiers( $2 ); } 3627 3552 ; -
src/SynTree/FunctionDecl.cc
r75d874a r0e16a2d 87 87 } // if 88 88 89 if ( !withExprs.empty() ) {90 os << indent << "... with clause" << std::endl;91 os << indent + 1;92 printAll( withExprs, os, indent + 1 );93 }94 95 89 if ( statements ) { 96 90 os << indent << "... with body" << endl << indent+1; -
tests/.expect/PRNG.x64.txt
r75d874a r0e16a2d 1 1 2 2 PRNG() PRNG(5) PRNG(0,5) 3 13944458589275087071 3 24 129977468648444256 0 45 23577274002988910212 26 8855179187835660146 3 37 9957620185645882382 4 18 1 3396406983727409795 0 59 3342782395220265920 0 510 1707651271867677937 1 011 16402561450140881681 0 112 17838519215740313729 4 213 7425936020594490136 4014 4174865704721714670 3 515 1 6055269689200152092 0 216 15091270195803594018 1 517 11807315541476180798 1 118 1 0697186588988060306 4 119 14665526411527044929 3 220 1 1289342279096164771 2521 16126980828050300615 1 422 7821578301767524260 4 13 2629641414891406278 3 0 4 11972157801652581900 3 5 5 9470682093934978437 2 2 6 316134424938305673 2 2 7 5572275127081588144 0 3 8 12394954141290188855 2 2 9 15386440704589550620 2 1 10 5760167266331356361 2 5 11 8021670258373873290 2 5 12 8813161879342109574 1 4 13 10525294799876107814 2 0 14 14801827301969351008 3 0 15 17016612914230924215 0 0 16 5485205801221744751 3 2 17 6143666691223938511 4 0 18 15086131934315954459 4 5 19 4547668615176940328 4 5 20 17718351571399359777 0 5 21 2636252641646208341 4 0 22 12820158953704882599 0 4 23 23 seed 1009 24 24 … … 33 33 34 34 prng() prng(5) prng(0,5) 35 13944458589275087071 3 236 129977468648444256 0 437 23577274002988910212 238 8855179187835660146 3 339 9957620185645882382 4 140 1 3396406983727409795 0 541 3342782395220265920 0 542 1707651271867677937 1 043 16402561450140881681 0 144 17838519215740313729 4 245 7425936020594490136 4046 4174865704721714670 3 547 1 6055269689200152092 0 248 15091270195803594018 1 549 11807315541476180798 1 150 1 0697186588988060306 4 151 14665526411527044929 3 252 1 1289342279096164771 2553 16126980828050300615 1 454 7821578301767524260 4 135 2629641414891406278 3 0 36 11972157801652581900 3 5 37 9470682093934978437 2 2 38 316134424938305673 2 2 39 5572275127081588144 0 3 40 12394954141290188855 2 2 41 15386440704589550620 2 1 42 5760167266331356361 2 5 43 8021670258373873290 2 5 44 8813161879342109574 1 4 45 10525294799876107814 2 0 46 14801827301969351008 3 0 47 17016612914230924215 0 0 48 5485205801221744751 3 2 49 6143666691223938511 4 0 50 15086131934315954459 4 5 51 4547668615176940328 4 5 52 17718351571399359777 0 5 53 2636252641646208341 4 0 54 12820158953704882599 0 4 55 55 seed 1009 56 56 … … 65 65 66 66 prng(t) prng(t,5) prng(t,0,5) 67 13944458589275087071 3 268 129977468648444256 0 469 23577274002988910212 270 8855179187835660146 3 371 9957620185645882382 4 172 1 3396406983727409795 0 573 3342782395220265920 0 574 1707651271867677937 1 075 16402561450140881681 0 176 17838519215740313729 4 277 7425936020594490136 4078 4174865704721714670 3 579 1 6055269689200152092 0 280 15091270195803594018 1 581 11807315541476180798 1 182 1 0697186588988060306 4 183 14665526411527044929 3 284 1 1289342279096164771 2585 16126980828050300615 1 486 7821578301767524260 4 167 2629641414891406278 3 0 68 11972157801652581900 3 5 69 9470682093934978437 2 2 70 316134424938305673 2 2 71 5572275127081588144 0 3 72 12394954141290188855 2 2 73 15386440704589550620 2 1 74 5760167266331356361 2 5 75 8021670258373873290 2 5 76 8813161879342109574 1 4 77 10525294799876107814 2 0 78 14801827301969351008 3 0 79 17016612914230924215 0 0 80 5485205801221744751 3 2 81 6143666691223938511 4 0 82 15086131934315954459 4 5 83 4547668615176940328 4 5 84 17718351571399359777 0 5 85 2636252641646208341 4 0 86 12820158953704882599 0 4 87 87 seed 1009 88 88 -
tests/.expect/PRNG.x86.txt
r75d874a r0e16a2d 1 1 2 2 PRNG() PRNG(5) PRNG(0,5) 3 2884683541 0 04 3465286746 2 45 3268922916 0 16 2396374907 3 07 2135076892 4 18 944377718 319 2204845346 3310 3736609533 0 411 4063231336 0 212 1075394776 0 213 712844808 4 014 4246343110 3 115 3793873837 2 116 3690340337 1417 319207944 1418 18 15791072 3 519 2581617261 1 520 3873329448 1 321 832631329 4 022 651551615 3 53 130161 1 1 4 4074541490 0 0 5 927506267 0 3 6 1991273445 1 3 7 669918146 2 3 8 519546860 1 1 9 1136699882 4 3 10 2130185384 3 1 11 992239050 0 5 12 2250903111 0 1 13 1544429724 3 2 14 1591091660 3 3 15 2511657707 2 4 16 1065770984 2 4 17 2412763405 4 4 18 1834447239 4 2 19 360289337 0 4 20 2449452027 1 1 21 3370425396 2 1 22 3109103043 0 3 23 23 seed 1009 24 24 25 25 Sequential 26 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%26 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 27 27 28 28 Concurrent 29 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%30 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%31 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%32 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%29 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 30 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 31 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 32 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 33 33 34 34 prng() prng(5) prng(0,5) 35 2884683541 0 036 3465286746 2 437 3268922916 0 138 2396374907 3 039 2135076892 4 140 944377718 3141 2204845346 3342 3736609533 0 443 4063231336 0 244 1075394776 0 245 712844808 4 046 4246343110 3 147 3793873837 2 148 3690340337 1449 319207944 1450 18 15791072 3 551 2581617261 1 552 3873329448 1 353 832631329 4 054 651551615 3 535 130161 1 1 36 4074541490 0 0 37 927506267 0 3 38 1991273445 1 3 39 669918146 2 3 40 519546860 1 1 41 1136699882 4 3 42 2130185384 3 1 43 992239050 0 5 44 2250903111 0 1 45 1544429724 3 2 46 1591091660 3 3 47 2511657707 2 4 48 1065770984 2 4 49 2412763405 4 4 50 1834447239 4 2 51 360289337 0 4 52 2449452027 1 1 53 3370425396 2 1 54 3109103043 0 3 55 55 seed 1009 56 56 57 57 Sequential 58 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%58 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 59 59 60 60 Concurrent 61 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%62 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%63 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%64 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%61 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 62 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 63 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 64 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 65 65 66 66 prng(t) prng(t,5) prng(t,0,5) 67 2884683541 0 068 3465286746 2 469 3268922916 0 170 2396374907 3 071 2135076892 4 172 944377718 3173 2204845346 3374 3736609533 0 475 4063231336 0 276 1075394776 0 277 712844808 4 078 4246343110 3 179 3793873837 2 180 3690340337 1481 319207944 1482 18 15791072 3 583 2581617261 1 584 3873329448 1 385 832631329 4 086 651551615 3 567 130161 1 1 68 4074541490 0 0 69 927506267 0 3 70 1991273445 1 3 71 669918146 2 3 72 519546860 1 1 73 1136699882 4 3 74 2130185384 3 1 75 992239050 0 5 76 2250903111 0 1 77 1544429724 3 2 78 1591091660 3 3 79 2511657707 2 4 80 1065770984 2 4 81 2412763405 4 4 82 1834447239 4 2 83 360289337 0 4 84 2449452027 1 1 85 3370425396 2 1 86 3109103043 0 3 87 87 seed 1009 88 88 89 89 Sequential 90 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%90 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 91 91 92 92 Concurrent 93 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%94 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%95 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%96 trials 100000000 buckets 100000 min 8 58 max 1147 avg 1000.0 std 31.5rstd 3.2%93 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 94 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 95 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% 96 trials 100000000 buckets 100000 min 867 max 1135 avg 1000.0 std 31.7 rstd 3.2% -
tests/.expect/nested_function.x86.txt
r75d874a r0e16a2d 1 total 2451 total 105 -
tests/concurrent/channels/parallel_harness.hfa
r75d874a r0e16a2d 100 100 101 101 int test( size_t Processors, size_t Channels, size_t Producers, size_t Consumers, size_t ChannelSize ) { 102 size_t Clusters = Processors;102 size_t Clusters = 1; 103 103 // create a cluster 104 104 cluster clus[Clusters]; … … 108 108 } 109 109 110 channels = a alloc( Channels );110 channels = anew( Channels ); 111 111 112 112 // sout | "Processors: " | Processors | " ProdsPerChan: " | Producers | " ConsPerChan: " | Consumers | "Channels: " | Channels | " Channel Size: " | ChannelSize; … … 150 150 151 151 } 152 152 // for ( i; Channels ) { 153 // // sout | get_count( channels[i] ); 154 // if ( get_count( channels[i] ) < Consumers ){ 155 // #ifdef BIG 156 // bigObject b{0}; 157 // #endif 158 // for ( j; Consumers ) { 159 // #ifdef BIG 160 // insert( channels[i], b ); 161 // #else 162 // insert( channels[i], 0 ); 163 // #endif 164 // } 165 // } 166 // } 153 167 sout | "cons"; 154 168 for ( i; Consumers * Channels ) { -
tests/concurrent/pthread/.expect/bounded_buffer.x64.txt
r75d874a r0e16a2d 1 producer total value is 3 97802 consumer total value is 3 97801 producer total value is 38160 2 consumer total value is 38160 -
tests/concurrent/pthread/.expect/bounded_buffer.x86.txt
r75d874a r0e16a2d 1 producer total value is 17702 consumer total value is 17701 producer total value is 45060 2 consumer total value is 45060
Note:
See TracChangeset
for help on using the changeset viewer.