Changes in / [299b8b28:fc1347d0]
- Files:
-
- 15 added
- 1 deleted
- 36 edited
-
doc/LaTeXmacros/common.sty (added)
-
doc/LaTeXmacros/common.tex (modified) (3 diffs)
-
doc/theses/mubeen_zulfiqar_MMath/allocator.tex (modified) (1 diff)
-
doc/theses/mubeen_zulfiqar_MMath/background.tex (modified) (1 diff)
-
doc/theses/mubeen_zulfiqar_MMath/benchmarks.tex (modified) (1 diff)
-
doc/theses/mubeen_zulfiqar_MMath/conclusion.tex (modified) (1 diff)
-
doc/theses/mubeen_zulfiqar_MMath/intro.tex (modified) (1 diff)
-
doc/user/Makefile (modified) (3 diffs)
-
doc/user/user.tex (modified) (10 diffs)
-
libcfa/src/common.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/alarm.cfa (modified) (5 diffs)
-
libcfa/src/concurrency/alarm.hfa (modified) (1 diff)
-
libcfa/src/concurrency/clib/cfathread.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/clib/cfathread.h (modified) (1 diff)
-
libcfa/src/concurrency/kernel.cfa (modified) (12 diffs)
-
libcfa/src/concurrency/kernel.hfa (modified) (7 diffs)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (6 diffs)
-
libcfa/src/concurrency/locks.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/locks.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/preemption.cfa (modified) (13 diffs)
-
libcfa/src/concurrency/ready_queue.cfa (modified) (7 diffs)
-
libcfa/src/concurrency/ready_subqueue.hfa (modified) (8 diffs)
-
libcfa/src/concurrency/stats.cfa (modified) (1 diff)
-
libcfa/src/containers/list.hfa (modified) (1 diff)
-
libcfa/src/exception.hfa (modified) (1 diff)
-
libcfa/src/executor.baseline.txt (added)
-
libcfa/src/executor.cfa (modified) (2 diffs)
-
libcfa/src/heap.cfa (modified) (2 diffs)
-
libcfa/src/iostream.cfa (modified) (3 diffs)
-
src/CodeGen/LinkOnce.cc (added)
-
src/CodeGen/LinkOnce.h (added)
-
src/CodeGen/module.mk (modified) (1 diff)
-
src/Concurrency/Keywords.cc (modified) (2 diffs)
-
src/InitTweak/InitTweak.cc (modified) (1 diff)
-
src/Virtual/Tables.cc (modified) (2 diffs)
-
src/main.cc (modified) (2 diffs)
-
tests/.expect/linkonce.txt (added)
-
tests/Makefile.am (modified) (2 diffs)
-
tests/array-container/array-md-sbscr-cases.cfa (modified) (6 diffs)
-
tests/concurrent/.expect/sleep.txt (added)
-
tests/concurrent/sleep.cfa (added)
-
tests/io/.expect/manipulatorsOutput4.txt (added)
-
tests/io/.expect/manipulatorsOutput4.x64.txt (deleted)
-
tests/link-once/main.cfa (added)
-
tests/link-once/partner.cfa (added)
-
tests/list/.expect/dlist-insert-remove.txt (modified) (6 diffs)
-
tests/list/dlist-insert-remove.cfa (modified) (76 diffs)
-
tests/zombies/linked-list-perf/experiment.cpp (added)
-
tests/zombies/linked-list-perf/experiment.koad (added)
-
tests/zombies/linked-list-perf/mike-old.hfa (added)
-
tests/zombies/linked-list-perf/mike-proto-list.hfa (added)
-
tests/zombies/linked-list-perf/thierry-subqueue-old-rip.hfa (added)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
r299b8b28 rfc1347d0 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Apr 27 12:03:17 202114 %% Update Count : 5 3913 %% Last Modified On : Sat May 8 08:48:37 2021 14 %% Update Count : 540 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 38 38 \usepackage{xspace} 39 39 \newcommand{\CFAIcon}{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}} % Cforall icon 40 \newcommand{\CFA}{\protect\CFAIcon\xspace} % CFA symbolic name41 \newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall non-icon name42 \newcommand{\Celeven}{\textrm{C11}\xspace} % C11 symbolic name40 \newcommand{\CFA}{\protect\CFAIcon\xspace} % CFA symbolic name 41 \newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall non-icon name 42 \newcommand{\Celeven}{\textrm{C11}\xspace} % C11 symbolic name 43 43 \newcommand{\CCIcon}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}} % C++ icon 44 \newcommand{\CC} {\protect\CCIcon\xspace}% C++ symbolic name44 \newcommand{\CC}[1][]{\protect\CCIcon{#1}\xspace} % C++ symbolic name 45 45 % numbers disallowed in latex variables names => use number names 46 \newcommand{\CCeleven}{\protect\CCIcon{11}\xspace} % C++11 symbolic name47 \newcommand{\CCfourteen}{\protect\CCIcon{14}\xspace} % C++14 symbolic name48 \newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace} % C++17 symbolic name49 \newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace} % C++20 symbolic name46 \newcommand{\CCeleven}{\protect\CCIcon{11}\xspace} % C++11 symbolic name 47 \newcommand{\CCfourteen}{\protect\CCIcon{14}\xspace} % C++14 symbolic name 48 \newcommand{\CCseventeen}{\protect\CCIcon{17}\xspace} % C++17 symbolic name 49 \newcommand{\CCtwenty}{\protect\CCIcon{20}\xspace} % C++20 symbolic name 50 50 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name 51 51 … … 153 153 % Latin abbreviation 154 154 \newcommand{\abbrevFont}{\textit} % set empty for no italics 155 % If not followed by a comma or colon, add a comma. 156 \newcommand{\CheckCommaColon}{\@ifnextchar{,}{}{\@ifnextchar{:}{}{,\xspace}}} 157 % If not followed by a period, add a period. 158 \newcommand{\CheckPeriod}{\@ifnextchar{.}{}{.\xspace}} 159 155 160 \@ifundefined{eg}{ 156 161 \newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.} 157 \newcommand*{\eg}{% 158 \@ifnextchar{,}{\EG}% 159 {\@ifnextchar{:}{\EG}% 160 {\EG,\xspace}}% 161 }}{}% 162 \newcommand{\eg}{\EG\CheckCommaColon} 163 }{}% 162 164 \@ifundefined{ie}{ 163 165 \newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.} 164 \newcommand*{\ie}{% 165 \@ifnextchar{,}{\IE}% 166 {\@ifnextchar{:}{\IE}% 167 {\IE,\xspace}}% 168 }}{}% 166 \newcommand{\ie}{\IE\CheckCommaColon} 167 }{}% 169 168 \@ifundefined{etc}{ 170 169 \newcommand{\ETC}{\abbrevFont{etc}} 171 \newcommand*{\etc}{% 172 \@ifnextchar{.}{\ETC}% 173 {\ETC.\xspace}% 174 }}{}% 170 \newcommand{\etc}{\ETC\CheckPeriod} 171 }{}% 175 172 \@ifundefined{etal}{ 176 173 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}} 177 \newcommand*{\etal}{% 178 \@ifnextchar{.}{\protect\ETAL}% 179 {\protect\ETAL.\xspace}% 180 }}{}% 174 \newcommand{\etal}{\ETAL\CheckPeriod} 175 }{}% 181 176 \@ifundefined{viz}{ 182 177 \newcommand{\VIZ}{\abbrevFont{viz}} 183 \newcommand*{\viz}{% 184 \@ifnextchar{.}{\VIZ}% 185 {\VIZ.\xspace}% 186 }}{}% 178 \newcommand{\viz}{\VIZ\CheckPeriod} 179 }{}% 187 180 \makeatother 188 181 -
doc/theses/mubeen_zulfiqar_MMath/allocator.tex
r299b8b28 rfc1347d0 1 \chapter{Allocator} 1 2 2 \chapter{Allocator} 3 ==================== 4 5 Writing Points: 6 7 Objective of uHeapLmmm. 8 Design philosophy. 9 Background and previous design of uHeapLmmm. 10 11 Distributed design of uHeapLmmm. 12 ----- SHOULD WE GIVE IMPLEMENTATION DETAILS HERE? ----- 13 > figure. 14 > Advantages of distributed design. 15 16 The new features added to uHeapLmmm (incl. malloc_size routine) 17 CFA alloc interface with examples. 18 > Why did we need it? 19 > The added benefits. 20 ----- SHOULD WE GIVE PERFORMANCE AND USABILITY COMPARISON OF DIFFERENT INTERFACES THAT WE TRIED? ----- 21 22 Performance evaluation using u-benchmark suite. 23 24 ==================== 3 25 4 26 \newpage -
doc/theses/mubeen_zulfiqar_MMath/background.tex
r299b8b28 rfc1347d0 1 1 \chapter{Background} 2 2 3 ==================== 4 5 Writing Points: 6 7 Classification of benchmarks. 8 Literature review of current benchmarks. 9 Features and limitations. 10 11 Literature review of current memory allocators. 12 Breakdown of memory allocation techniques. 13 Fetures and limitations. 14 15 ==================== 16 3 17 \cite{Wasik08} -
doc/theses/mubeen_zulfiqar_MMath/benchmarks.tex
r299b8b28 rfc1347d0 1 1 \chapter{Benchmarks} 2 3 ==================== 4 5 Writing Points: 6 7 Performance matrices of memory allocation. 8 9 Aim of micro benchmark suite. 10 ----- SHOULD WE GIVE IMPLEMENTATION DETAILS HERE? ----- 11 A complete list of benchmarks in micro benchmark suite. 12 13 One detailed section for each benchmark in micro benchmark suite including: 14 > The introduction of the benchmark. 15 > Figure. 16 > Results with popular memory allocators. 17 18 Summarize performance of current memory allocators. 19 20 ==================== -
doc/theses/mubeen_zulfiqar_MMath/conclusion.tex
r299b8b28 rfc1347d0 1 1 \chapter{Conclusion} 2 3 ==================== 4 5 Writing Points: 6 7 Summarize u-benchmark suite. 8 Summarize uHeapLmmm. 9 Make recommendations on memory allocator design. 10 11 ==================== -
doc/theses/mubeen_zulfiqar_MMath/intro.tex
r299b8b28 rfc1347d0 1 1 \chapter{Introduction} 2 3 ==================== 4 5 Writing Points: 6 7 Introduce dynamic memory allocation with brief background. 8 Scope of the thesis. 9 Importance of memory allocation and micro benhmark suite. 10 11 Research problem. 12 Research objectives. 13 The vision behind cfa-malloc. 14 15 An outline of the thesis. 16 17 ==================== -
doc/user/Makefile
r299b8b28 rfc1347d0 61 61 62 62 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \ 63 ${Macros}/common. tex${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build}63 ${Macros}/common.sty ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build} 64 64 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 65 65 if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi … … 68 68 -${BibTeX} ${Build}/${basename $@} 69 69 # Some citations reference others so run again to resolve these citations 70 ${LaTeX} ${basename $@}.tex70 # ${LaTeX} ${basename $@}.tex 71 71 -${BibTeX} ${Build}/${basename $@} 72 72 # Make index from *.aux entries and input index at end of document … … 75 75 ${LaTeX} ${basename $@}.tex 76 76 # Run again to get index title into table of contents 77 ${LaTeX} ${basename $@}.tex77 # ${LaTeX} ${basename $@}.tex 78 78 79 79 ## Define the default recipes. -
doc/user/user.tex
r299b8b28 rfc1347d0 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Wed Apr 28 21:48:59202114 %% Update Count : 50 5113 %% Last Modified On : Sat May 8 08:51:33 2021 14 %% Update Count : 5062 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 65 65 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 66 66 % math escape $...$ (dollar symbol) 67 \input{common} % common CFA document macros 67 \usepackage{common} % common CFA document macros 68 %\input{common} % common CFA document macros 68 69 \setlength{\gcolumnposn}{3in} 69 70 \CFAStyle % use default CFA format-style … … 585 586 For example, the octal ©0© or hexadecimal ©0x© prefix may end with an underscore ©0_377© or ©0x_ff©; 586 587 the exponent infix ©E© may start or end with an underscore ©1.0_E10©, ©1.0E_10© or ©1.0_E_10©; 587 the type suffixes ©U©, ©L©, etc.may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©.588 the type suffixes ©U©, ©L©, \etc may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©. 588 589 \end{enumerate} 589 590 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (many cultures use comma and/or period among digits for the same purpose). … … 1570 1571 \end{cquote} 1571 1572 1572 All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg:1573 All type qualifiers, \eg ©const©, ©volatile©, \etc, are used in the normal way with the new declarations and also appear left to right, \eg: 1573 1574 \begin{cquote} 1574 1575 \begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}} … … 1590 1591 \end{tabular} 1591 1592 \end{cquote} 1592 All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}1593 All declaration qualifiers, \eg ©extern©, ©static©, \etc, are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1593 1594 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg: 1594 1595 \begin{cquote} … … 3147 3148 also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple. 3148 3149 3149 Since tuple-index expressions are a form of member-access expression, it is possible to use tuple-index expressions in conjunction with member-access expressions to restructure a tuple (\eg, rearrange components, drop components, duplicate components, etc.).3150 Since tuple-index expressions are a form of member-access expression, it is possible to use tuple-index expressions in conjunction with member-access expressions to restructure a tuple (\eg, rearrange components, drop components, duplicate components, \etc). 3150 3151 \begin{cfa} 3151 3152 [ int, int, long, double ] x; … … 3972 3973 3973 3974 \item 3974 \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global sep erator setting.3975 \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global separator setting. 3975 3976 \begin{cfa}[belowskip=0pt] 3976 3977 sout | 1 | sepOff | 2 | 3; $\C{// turn off implicit separator for the next item}$ … … 5659 5660 \item 5660 5661 Package: a container to organize modules for distribution; It has attributes like name, author, 5661 version, dependences, etc.5662 \item 5663 Project: a working set for a \CFA project; It has attributes like name, author, version, dependences, etc.5662 version, dependences, \etc. 5663 \item 5664 Project: a working set for a \CFA project; It has attributes like name, author, version, dependences, \etc. 5664 5665 \end{itemize} 5665 5666 … … 5798 5799 5799 5800 A package is defined by putting a project description file, Do.prj, with one or more modules into a directory. 5800 This project description file contains the package's meta data, including package name, author, version, dependences, etc.5801 This project description file contains the package's meta data, including package name, author, version, dependences, \etc. 5801 5802 It should be in the root of the package directory. 5802 5803 … … 5855 5856 Module: a container to organize a set of related types and methods; It has a module name, and several interfaces visible from outside 5856 5857 \item 5857 Package: a container to organize modules for distribution; It has attributes like name, author, version, dependences, etc.5858 \item 5859 Project: a working set for a \CFA project; It has attributes like name, author, version, dependences, etc.5858 Package: a container to organize modules for distribution; It has attributes like name, author, version, dependences, \etc. 5859 \item 5860 Project: a working set for a \CFA project; It has attributes like name, author, version, dependences, \etc. 5860 5861 \end{itemize} 5861 5862 -
libcfa/src/common.hfa
r299b8b28 rfc1347d0 10 10 // Created On : Wed Jul 11 17:54:36 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 15 08:51:29 202013 // Update Count : 1 412 // Last Modified On : Wed May 5 14:02:04 2021 13 // Update Count : 18 14 14 // 15 15 … … 67 67 68 68 static inline { 69 char min( char t1, char t2 ) { return t1 < t2 ? t1 : t2; } // optimization 70 intptr_t min( intptr_t t1, intptr_t t2 ) { return t1 < t2 ? t1 : t2; } // optimization 71 uintptr_t min( uintptr_t t1, uintptr_t t2 ) { return t1 < t2 ? t1 : t2; } // optimization 69 char min( char v1, char v2 ) { return v1 < v2 ? v1 : v2; } // optimization 70 int min( int v1, int v2 ) { return v1 < v2 ? v1 : v2; } 71 unsigned int min( unsigned int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 72 long int min( long int v1, long int v2 ) { return v1 < v2 ? v1 : v2; } 73 unsigned long int min( unsigned long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 74 long long int min( long long int v1, long long int v2 ) { return v1 < v2 ? v1 : v2; } 75 unsigned long long int min( unsigned long long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 72 76 forall( T | { int ?<?( T, T ); } ) 73 T min( T t1, T t2 ) { return t1 < t2 ? t1 : t2; }77 T min( T v1, T v2 ) { return v1 < v2 ? v1 : v2; } 74 78 75 char max( char t1, char t2 ) { return t1 > t2 ? t1 : t2; } // optimization 76 intptr_t max( intptr_t t1, intptr_t t2 ) { return t1 > t2 ? t1 : t2; } // optimization 77 uintptr_t max( uintptr_t t1, uintptr_t t2 ) { return t1 > t2 ? t1 : t2; } // optimization 79 char max( char v1, char v2 ) { return v1 > v2 ? v1 : v2; } // optimization 80 int max( int v1, int v2 ) { return v1 > v2 ? v1 : v2; } 81 unsigned int max( unsigned int v1, unsigned int v2 ) { return v1 > v2 ? v1 : v2; } 82 long int max( long int v1, long int v2 ) { return v1 > v2 ? v1 : v2; } 83 unsigned long int max( unsigned long int v1, unsigned long int v2 ) { return v1 > v2 ? v1 : v2; } 84 long long int max( long long int v1, long long int v2 ) { return v1 > v2 ? v1 : v2; } 85 unsigned long long int max( unsigned long long int v1, unsigned long long int v2 ) { return v1 > v2 ? v1 : v2; } 78 86 forall( T | { int ?>?( T, T ); } ) 79 T max( T t1, T t2 ) { return t1 > t2 ? t1 : t2; }87 T max( T v1, T v2 ) { return v1 > v2 ? v1 : v2; } 80 88 81 89 forall( T | { T min( T, T ); T max( T, T ); } ) -
libcfa/src/concurrency/alarm.cfa
r299b8b28 rfc1347d0 38 38 39 39 void __kernel_set_timer( Duration alarm ) { 40 verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm`ns); 41 setitimer( ITIMER_REAL, &(itimerval){ alarm }, 0p ); 40 alarm = max(alarm, 1`us); 41 itimerval otv @= { 0 }; 42 getitimer( ITIMER_REAL, &otv ); 43 Duration od = { otv.it_value }; 44 if(od == 0 || od > alarm) { 45 setitimer( ITIMER_REAL, &(itimerval){ alarm }, 0p ); 46 } 42 47 } 43 48 … … 46 51 //============================================================================================= 47 52 48 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period) with( this ) { 53 void ?{}( alarm_node_t & this, $thread * thrd, Duration alarm, Duration period) with( this ) { 54 this.initial = alarm; 55 this.period = period; 49 56 this.thrd = thrd; 50 this.alarm = alarm; 51 this.period = period; 57 this.timeval = __kernel_get_time() + alarm; 52 58 set = false; 53 59 type = User; 54 60 } 55 61 56 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period ) with( this ) { 62 void ?{}( alarm_node_t & this, processor * proc, Duration alarm, Duration period ) with( this ) { 63 this.initial = alarm; 64 this.period = period; 57 65 this.proc = proc; 58 this.alarm = alarm; 59 this.period = period; 66 this.timeval = __kernel_get_time() + alarm; 60 67 set = false; 61 68 type = Kernel; 62 69 } 63 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period ) with( this ) { 64 this.alarm = alarm; 65 this.period = period; 70 void ?{}( alarm_node_t & this, Alarm_Callback callback, Duration alarm, Duration period ) with( this ) { 66 71 this.callback = callback; 72 this.initial = alarm; 73 this.period = period; 74 this.timeval = __kernel_get_time() + alarm; 67 75 set = false; 68 76 type = Callback; … … 77 85 void insert( alarm_list_t * this, alarm_node_t * n ) { 78 86 alarm_node_t * it = & (*this)`first; 79 while( it && (n-> alarm > it->alarm) ) {87 while( it && (n->timeval > it->timeval) ) { 80 88 it = & (*it)`next; 81 89 } … … 105 113 lock( event_kernel->lock __cfaabi_dbg_ctx2 ); 106 114 { 107 verify( validate( alarms ) ); 108 bool first = ! & alarms`first; 115 /* paranoid */ verify( validate( alarms ) ); 109 116 110 __cfadbg_print_safe( preemption, " KERNEL: alarm inserting %p (%lu).\n", this, this->alarm.tn ); 117 Time curr = __kernel_get_time(); 118 __cfadbg_print_safe( preemption, " KERNEL: alarm inserting %p (%lu -> %lu).\n", this, curr.tn, this->timeval.tn ); 111 119 insert( &alarms, this ); 112 if( first ) { 113 __kernel_set_timer( alarms`first.alarm - __kernel_get_time() ); 114 } 120 __kernel_set_timer( this->timeval - curr); 115 121 } 116 122 unlock( event_kernel->lock ); … … 136 142 137 143 void sleep( Duration duration ) { 138 alarm_node_t node = { active_thread(), __kernel_get_time() +duration, 0`s };144 alarm_node_t node = { active_thread(), duration, 0`s }; 139 145 140 146 register_self( &node ); -
libcfa/src/concurrency/alarm.hfa
r299b8b28 rfc1347d0 46 46 47 47 struct alarm_node_t { 48 Time alarm;// time when alarm goes off49 Duration period; // if > 0 => period of alarm48 Duration initial; // time when alarm goes off 49 Duration period; // if > 0 => period of alarm 50 50 51 DLISTED_MGD_IMPL_IN(alarm_node_t)51 inline dlink(alarm_node_t); 52 52 53 53 union { 54 $thread * thrd; // thrd who created event55 processor * proc; // proc who created event56 Alarm_Callback callback; // callback to handle event54 $thread * thrd; // thrd who created event 55 processor * proc; // proc who created event 56 Alarm_Callback callback; // callback to handle event 57 57 }; 58 58 59 bool set :1; // whether or not the alarm has be registered 60 enum alarm_type type; // true if this is not a user defined alarm 59 Time timeval; // actual time at which the alarm goes off 60 enum alarm_type type; // true if this is not a user defined alarm 61 bool set :1; // whether or not the alarm has be registered 61 62 }; 62 DLISTED_MGD_IMPL_OUT(alarm_node_t)63 P9_EMBEDDED( alarm_node_t, dlink(alarm_node_t) ) 63 64 64 void ?{}( alarm_node_t & this, $thread * thrd, Timealarm, Duration period );65 void ?{}( alarm_node_t & this, processor * proc, Timealarm, Duration period );66 void ?{}( alarm_node_t & this, Alarm_Callback callback, Timealarm, Duration period );65 void ?{}( alarm_node_t & this, $thread * thrd, Duration alarm, Duration period ); 66 void ?{}( alarm_node_t & this, processor * proc, Duration alarm, Duration period ); 67 void ?{}( alarm_node_t & this, Alarm_Callback callback, Duration alarm, Duration period ); 67 68 void ^?{}( alarm_node_t & this ); 68 69 69 typedef dlist(alarm_node_t , alarm_node_t) alarm_list_t;70 typedef dlist(alarm_node_t) alarm_list_t; 70 71 71 72 void insert( alarm_list_t * this, alarm_node_t * n ); -
libcfa/src/concurrency/clib/cfathread.cfa
r299b8b28 rfc1347d0 27 27 extern void __cfactx_invoke_thread(void (*main)(void *), void * this); 28 28 } 29 30 extern Time __kernel_get_time(); 29 31 30 32 //================================================================================ … … 265 267 int cfathread_cond_timedwait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut, const struct timespec *restrict abstime) __attribute__((nonnull (1,2,3))) { 266 268 Time t = { *abstime }; 267 if( wait( (*cond)->impl, (*mut)->impl, t ) ) { 269 timespec curr; 270 clock_gettime( CLOCK_REALTIME, &curr ); 271 Time c = { curr }; 272 if( wait( (*cond)->impl, (*mut)->impl, t - c ) ) { 268 273 return 0; 269 274 } -
libcfa/src/concurrency/clib/cfathread.h
r299b8b28 rfc1347d0 80 80 81 81 typedef struct cfathread_cond_attr { 82 // WARNING: adding support for pthread_condattr_setclock would require keeping track of the clock 83 // and reading it in cond_timedwait 82 84 } cfathread_condattr_t; 83 85 typedef struct cfathread_condition * cfathread_cond_t; -
libcfa/src/concurrency/kernel.cfa
r299b8b28 rfc1347d0 171 171 preemption_scope scope = { this }; 172 172 173 __STATS( unsigned long long last_tally = rdtscl(); )174 175 173 // if we need to run some special setup, now is the time to do it. 176 174 if(this->init.thrd) { … … 184 182 MAIN_LOOP: 185 183 for() { 186 #if 1 184 #define OLD_MAIN 1 185 #if OLD_MAIN 187 186 // Check if there is pending io 188 187 __maybe_io_drain( this ); … … 259 258 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 260 259 261 #if !defined(__CFA_NO_STATISTICS__)262 unsigned long long curr = rdtscl();263 if(curr > (last_tally + 500000000)) {264 __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);265 last_tally = curr;266 }267 #endif268 269 260 if(this->io.pending && !this->io.dirty) { 270 261 __cfa_io_flush( this ); … … 272 263 273 264 #else 274 265 #warning new kernel loop 275 266 SEARCH: { 276 267 /* paranoid */ verify( ! __preemption_enabled() ); 277 /* paranoid */ verify( kernelTLS().this_proc_id );278 268 279 269 // First, lock the scheduler since we are searching for a thread … … 288 278 289 279 // Spin a little on I/O, just in case 290 for(25) {280 for(5) { 291 281 __maybe_io_drain( this ); 292 282 readyThread = pop_fast( this->cltr ); … … 295 285 296 286 // no luck, try stealing a few times 297 for(25) {287 for(5) { 298 288 if( __maybe_io_drain( this ) ) { 299 289 readyThread = pop_fast( this->cltr ); … … 333 323 } 334 324 335 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl()); )325 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); ) 336 326 __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle); 337 327 … … 341 331 // __enable_interrupts_hard(); 342 332 343 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); )333 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); ) 344 334 345 335 // We were woken up, remove self from idle … … 351 341 352 342 RUN_THREAD: 353 /* paranoid */ verify( kernelTLS().this_proc_id );354 343 /* paranoid */ verify( ! __preemption_enabled() ); 355 344 /* paranoid */ verify( readyThread ); … … 363 352 // Are we done? 364 353 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 365 366 #if !defined(__CFA_NO_STATISTICS__)367 unsigned long long curr = rdtscl();368 if(curr > (last_tally + 500000000)) {369 __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);370 last_tally = curr;371 }372 #endif373 354 374 355 if(this->io.pending && !this->io.dirty) { … … 887 868 unsigned tail = *ctx->cq.tail; 888 869 if(head == tail) return false; 870 #if OLD_MAIN 889 871 ready_schedule_lock(); 890 872 ret = __cfa_io_drain( proc ); 891 873 ready_schedule_unlock(); 874 #else 875 ret = __cfa_io_drain( proc ); 876 #endif 892 877 #endif 893 878 return ret; … … 918 903 } 919 904 905 static void crawl_list( cluster * cltr, dlist(processor) & list, unsigned count ) { 906 /* paranoid */ verify( cltr->stats ); 907 908 processor * it = &list`first; 909 for(unsigned i = 0; i < count; i++) { 910 /* paranoid */ verifyf( it, "Unexpected null iterator, at index %u of %u\n", i, count); 911 /* paranoid */ verify( it->local_data->this_stats ); 912 __tally_stats( cltr->stats, it->local_data->this_stats ); 913 it = &(*it)`next; 914 } 915 } 916 917 void crawl_cluster_stats( cluster & this ) { 918 // Stop the world, otherwise stats could get really messed-up 919 // this doesn't solve all problems but does solve many 920 // so it's probably good enough 921 uint_fast32_t last_size = ready_mutate_lock(); 922 923 crawl_list(&this, this.procs.actives, this.procs.total - this.procs.idle); 924 crawl_list(&this, this.procs.idles , this.procs.idle ); 925 926 // Unlock the RWlock 927 ready_mutate_unlock( last_size ); 928 } 929 930 920 931 void print_stats_now( cluster & this, int flags ) { 932 crawl_cluster_stats( this ); 921 933 __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this ); 922 934 } -
libcfa/src/concurrency/kernel.hfa
r299b8b28 rfc1347d0 107 107 108 108 // Link lists fields 109 DLISTED_MGD_IMPL_IN(processor)109 inline dlink(processor); 110 110 111 111 // special init fields … … 117 117 } init; 118 118 119 struct KernelThreadData * local_data; 120 119 121 #if !defined(__CFA_NO_STATISTICS__) 120 122 int print_stats; … … 127 129 #endif 128 130 }; 131 P9_EMBEDDED( processor, dlink(processor) ) 129 132 130 133 void ?{}(processor & this, const char name[], struct cluster & cltr); … … 134 137 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; } 135 138 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster}; } 136 137 DLISTED_MGD_IMPL_OUT(processor)138 139 139 140 //----------------------------------------------------------------------------- … … 146 147 147 148 // Aligned timestamps which are used by the relaxed ready queue 148 struct __attribute__((aligned(128))) __timestamp_t; 149 void ?{}(__timestamp_t & this); 150 void ^?{}(__timestamp_t & this); 149 struct __attribute__((aligned(128))) __timestamp_t { 150 volatile unsigned long long tv; 151 }; 152 153 static inline void ?{}(__timestamp_t & this) { this.tv = 0; } 154 static inline void ^?{}(__timestamp_t & this) {} 151 155 152 156 //TODO adjust cache size to ARCHITECTURE … … 171 175 void ?{}(__ready_queue_t & this); 172 176 void ^?{}(__ready_queue_t & this); 177 #if !defined(__CFA_NO_STATISTICS__) 178 unsigned cnt(const __ready_queue_t & this, unsigned idx); 179 #endif 173 180 174 181 // Idle Sleep … … 184 191 185 192 // List of idle processors 186 dlist(processor , processor) idles;193 dlist(processor) idles; 187 194 188 195 // List of active processors 189 dlist(processor , processor) actives;196 dlist(processor) actives; 190 197 }; 191 198 -
libcfa/src/concurrency/kernel/startup.cfa
r299b8b28 rfc1347d0 228 228 __init_stats( __cfaabi_tls.this_stats ); 229 229 #endif 230 mainProcessor->local_data = &__cfaabi_tls; 230 231 231 232 // Enable preemption … … 282 283 #endif 283 284 285 mainProcessor->local_data = 0p; 286 284 287 unregister_tls( mainProcessor ); 285 288 … … 329 332 __cfaabi_tls.this_thread = 0p; 330 333 __cfaabi_tls.preemption_state.[enabled, disable_count] = [false, 1]; 334 proc->local_data = &__cfaabi_tls; 331 335 332 336 register_tls( proc ); … … 368 372 #endif 369 373 #endif 374 375 proc->local_data = 0p; 370 376 371 377 unregister_tls( proc ); … … 490 496 this.rdq.id = -1u; 491 497 this.rdq.target = -1u; 492 this.rdq.cutoff = -1ull;498 this.rdq.cutoff = 0ull; 493 499 do_terminate = false; 494 500 preemption_alarm = 0p; … … 500 506 501 507 this.init.thrd = initT; 508 509 this.local_data = 0p; 502 510 503 511 this.idle = eventfd(0, 0); -
libcfa/src/concurrency/locks.cfa
r299b8b28 rfc1347d0 191 191 }; 192 192 193 void ?{}( alarm_node_wrap(L) & this, Timealarm, Duration period, Alarm_Callback callback, condition_variable(L) * c, info_thread(L) * i ) {193 void ?{}( alarm_node_wrap(L) & this, Duration alarm, Duration period, Alarm_Callback callback, condition_variable(L) * c, info_thread(L) * i ) { 194 194 this.alarm_node{ callback, alarm, period }; 195 195 this.cond = c; … … 313 313 314 314 // helper for wait()'s' with a timeout 315 void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Timet ) with(this) {315 void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t ) with(this) { 316 316 lock( lock __cfaabi_dbg_ctx2 ); 317 317 size_t recursion_count = queue_and_get_recursion(this, &info); … … 340 340 void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) { WAIT( info, &l ) } 341 341 342 bool wait( condition_variable(L) & this, Duration duration ) with(this) { WAIT_TIME( 0 , 0p , __kernel_get_time() + duration ) } 343 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, 0p , __kernel_get_time() + duration ) } 344 bool wait( condition_variable(L) & this, Time time ) with(this) { WAIT_TIME( 0 , 0p , time ) } 345 bool wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, 0p , time ) } 346 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { WAIT_TIME( 0 , &l , __kernel_get_time() + duration ) } 347 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , __kernel_get_time() + duration ) } 348 bool wait( condition_variable(L) & this, L & l, Time time ) with(this) { WAIT_TIME( 0 , &l , time ) } 349 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, &l , time ) } 342 bool wait( condition_variable(L) & this, Duration duration ) with(this) { WAIT_TIME( 0 , 0p , duration ) } 343 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, 0p , duration ) } 344 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { WAIT_TIME( 0 , &l , duration ) } 345 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , duration ) } 350 346 } 351 347 -
libcfa/src/concurrency/locks.hfa
r299b8b28 rfc1347d0 290 290 bool wait( condition_variable(L) & this, Duration duration ); 291 291 bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ); 292 bool wait( condition_variable(L) & this, Time time );293 bool wait( condition_variable(L) & this, uintptr_t info, Time time );294 292 295 293 void wait( condition_variable(L) & this, L & l ); … … 297 295 bool wait( condition_variable(L) & this, L & l, Duration duration ); 298 296 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ); 299 bool wait( condition_variable(L) & this, L & l, Time time ); 300 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ); 301 } 297 } -
libcfa/src/concurrency/preemption.cfa
r299b8b28 rfc1347d0 18 18 19 19 #include "preemption.hfa" 20 20 21 #include <assert.h> 21 22 … … 26 27 #include <limits.h> // PTHREAD_STACK_MIN 27 28 29 #include "bits/debug.hfa" 28 30 #include "bits/signal.hfa" 29 31 #include "kernel_private.hfa" … … 105 107 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) { 106 108 if( ! & (*alarms)`first ) return 0p; // If no alarms return null 107 if( (*alarms)`first. alarm>= currtime ) return 0p; // If alarms head not expired return null109 if( (*alarms)`first.timeval >= currtime ) return 0p; // If alarms head not expired return null 108 110 return pop(alarms); // Otherwise just pop head 109 111 } … … 141 143 if( period > 0 ) { 142 144 __cfadbg_print_buffer_local( preemption, " KERNEL: alarm period is %lu.\n", period`ns ); 143 node-> alarm = currtime + period;// Alarm is periodic, add currtime to it (used cached current time)145 node->timeval = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) 144 146 insert( alarms, node ); // Reinsert the node for the next time it triggers 145 147 } … … 148 150 // If there are still alarms pending, reset the timer 149 151 if( & (*alarms)`first ) { 150 Duration delta = (*alarms)`first.alarm - currtime; 151 Duration capped = max(delta, 50`us); 152 __kernel_set_timer( capped ); 152 Duration delta = (*alarms)`first.timeval - currtime; 153 __kernel_set_timer( delta ); 153 154 } 154 155 } … … 160 161 // Alarms need to be enabled 161 162 if ( duration > 0 && ! alarm->set ) { 162 alarm-> alarm = __kernel_get_time() +duration;163 alarm->period = duration;163 alarm->initial = duration; 164 alarm->period = duration; 164 165 register_self( alarm ); 165 166 } … … 167 168 else if ( duration == 0 && alarm->set ) { 168 169 unregister_self( alarm ); 169 alarm-> alarm= 0;170 alarm->period = 0;170 alarm->initial = 0; 171 alarm->period = 0; 171 172 } 172 173 // If alarm is different from previous, change it 173 174 else if ( duration > 0 && alarm->period != duration ) { 174 175 unregister_self( alarm ); 175 alarm-> alarm = __kernel_get_time() +duration;176 alarm->period = duration;176 alarm->initial = duration; 177 alarm->period = duration; 177 178 register_self( alarm ); 178 179 } … … 599 600 600 601 // Notify the alarm thread of the shutdown 601 sigval val = { 1 }; 602 sigval val; 603 val.sival_int = 0; 602 604 pthread_sigqueue( alarm_thread, SIGALRM, val ); 603 605 … … 619 621 // Used by thread to control when they want to receive preemption signals 620 622 void ?{}( preemption_scope & this, processor * proc ) { 621 (this.alarm){ proc, (Time){ 0 }, 0`s };623 (this.alarm){ proc, 0`s, 0`s }; 622 624 this.proc = proc; 623 625 this.proc->preemption_alarm = &this.alarm; … … 705 707 int sig = sigwaitinfo( &mask, &info ); 706 708 709 __cfadbg_print_buffer_decl ( preemption, " KERNEL: sigwaitinfo returned %d, c: %d, v: %d\n", sig, info.si_code, info.si_value.sival_int ); 710 __cfadbg_print_buffer_local( preemption, " KERNEL: SI_QUEUE %d, SI_TIMER %d, SI_KERNEL %d\n", SI_QUEUE, SI_TIMER, SI_KERNEL ); 711 707 712 if( sig < 0 ) { 708 713 //Error! … … 711 716 case EAGAIN : 712 717 case EINTR : 713 {__cfa abi_dbg_print_buffer_decl(" KERNEL: Spurious wakeup %d.\n", err );}718 {__cfadbg_print_buffer_local( preemption, " KERNEL: Spurious wakeup %d.\n", err );} 714 719 continue; 715 720 case EINVAL : … … 723 728 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 724 729 725 // __cfaabi_dbg_print_safe( "Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );726 730 // Switch on the code (a.k.a. the sender) to 727 731 switch( info.si_code ) 728 732 { 733 // Signal was not sent by the kernel but by an other thread 734 case SI_QUEUE: 735 // other threads may signal the alarm thread to shut it down 736 // or to manual cause the preemption tick 737 // use info.si_value and handle the case here 738 switch( info.si_value.sival_int ) { 739 case 0: 740 goto EXIT; 741 default: 742 abort( "SI_QUEUE with val %d", info.si_value.sival_int); 743 } 744 // fallthrough 729 745 // Timers can apparently be marked as sent for the kernel 730 746 // In either case, tick preemption … … 736 752 unlock( event_kernel->lock ); 737 753 break; 738 // Signal was not sent by the kernel but by an other thread739 case SI_QUEUE:740 // For now, other thread only signal the alarm thread to shut it down741 // If this needs to change use info.si_value and handle the case here742 goto EXIT;743 754 } 744 755 } -
libcfa/src/concurrency/ready_queue.cfa
r299b8b28 rfc1347d0 398 398 399 399 if(proc->rdq.target == -1u) { 400 unsigned long long min = ts(lanes.data[proc->rdq.id]); 401 for(int i = 0; i < READYQ_SHARD_FACTOR; i++) { 402 unsigned long long tsc = ts(lanes.data[proc->rdq.id + i]); 403 if(tsc < min) min = tsc; 404 } 405 proc->rdq.cutoff = min; 400 406 proc->rdq.target = __tls_rand() % lanes.count; 401 unsigned it1 = proc->rdq.itr;402 unsigned it2 = proc->rdq.itr + 1;403 unsigned idx1 = proc->rdq.id + (it1 % READYQ_SHARD_FACTOR);404 unsigned idx2 = proc->rdq.id + (it2 % READYQ_SHARD_FACTOR);405 unsigned long long tsc1 = ts(lanes.data[idx1]);406 unsigned long long tsc2 = ts(lanes.data[idx2]);407 proc->rdq.cutoff = min(tsc1, tsc2);408 if(proc->rdq.cutoff == 0) proc->rdq.cutoff = -1ull;409 407 } 410 408 else { … … 418 416 419 417 for(READYQ_SHARD_FACTOR) { 420 unsigned i = proc->rdq.id + ( --proc->rdq.itr% READYQ_SHARD_FACTOR);418 unsigned i = proc->rdq.id + (proc->rdq.itr++ % READYQ_SHARD_FACTOR); 421 419 if($thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t; 422 420 } … … 469 467 // Actually pop the list 470 468 struct $thread * thrd; 471 thrd = pop(lane); 469 unsigned long long tsv; 470 [thrd, tsv] = pop(lane); 472 471 473 472 /* paranoid */ verify(thrd); … … 481 480 482 481 #if defined(USE_WORK_STEALING) 483 lanes.tscs[w].tv = t hrd->link.ts;482 lanes.tscs[w].tv = tsv; 484 483 #endif 485 484 … … 553 552 } 554 553 555 static void assign_list(unsigned & value, dlist(processor , processor) & list, unsigned count) {554 static void assign_list(unsigned & value, dlist(processor) & list, unsigned count) { 556 555 processor * it = &list`first; 557 556 for(unsigned i = 0; i < count; i++) { … … 663 662 while(!is_empty(lanes.data[idx])) { 664 663 struct $thread * thrd; 665 thrd = pop(lanes.data[idx]); 664 unsigned long long _; 665 [thrd, _] = pop(lanes.data[idx]); 666 666 667 667 push(cltr, thrd); … … 702 702 /* paranoid */ verify( ready_mutate_islocked() ); 703 703 } 704 705 #if !defined(__CFA_NO_STATISTICS__) 706 unsigned cnt(const __ready_queue_t & this, unsigned idx) { 707 /* paranoid */ verify(this.lanes.count > idx); 708 return this.lanes.data[idx].cnt; 709 } 710 #endif -
libcfa/src/concurrency/ready_subqueue.hfa
r299b8b28 rfc1347d0 13 13 14 14 __thread_desc_link anchor; 15 16 #if !defined(__CFA_NO_STATISTICS__) 17 unsigned cnt; 18 #endif 15 19 }; 16 20 … … 29 33 this.anchor.next = 0p; 30 34 this.anchor.ts = 0; 35 #if !defined(__CFA_NO_STATISTICS__) 36 this.cnt = 0; 37 #endif 31 38 32 39 // We add a boat-load of assertions here because the anchor code is very fragile 40 /* paranoid */ _Static_assert( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) ); 33 41 /* paranoid */ verify( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) ); 34 42 /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( $thread, link )) == (uintptr_t)(&this.anchor) ); … … 53 61 // Push a thread onto this lane 54 62 // returns true of lane was empty before push, false otherwise 55 void push( __intrusive_lane_t & this, $thread * node ) { 63 static inline void push( __intrusive_lane_t & this, $thread * node ) { 64 /* paranoid */ verify( this.lock ); 56 65 /* paranoid */ verify( node->link.next == 0p ); 57 66 /* paranoid */ verify( node->link.ts == 0 ); … … 72 81 this.prev->link.ts = rdtscl(); 73 82 this.prev = node; 83 #if !defined(__CFA_NO_STATISTICS__) 84 this.cnt++; 85 #endif 74 86 } 75 87 … … 77 89 // returns popped 78 90 // returns true of lane was empty before push, false otherwise 79 $thread * pop( __intrusive_lane_t & this ) { 91 static inline [* $thread, unsigned long long] pop( __intrusive_lane_t & this ) { 92 /* paranoid */ verify( this.lock ); 80 93 /* paranoid */ verify( this.anchor.next != 0p ); 81 94 /* paranoid */ verify( this.anchor.ts != 0 ); 82 95 83 96 // Get the relevant nodes locally 97 unsigned long long ts = this.anchor.ts; 84 98 $thread * node = this.anchor.next; 85 99 this.anchor.next = node->link.next; … … 88 102 node->link.next = 0p; 89 103 node->link.ts = 0; 104 #if !defined(__CFA_NO_STATISTICS__) 105 this.cnt--; 106 #endif 90 107 91 108 // Update head time stamp … … 94 111 /* paranoid */ verify( node->link.next == 0p ); 95 112 /* paranoid */ verify( node->link.ts == 0 ); 96 return node;113 return [node, ts]; 97 114 } 98 115 … … 107 124 return this.anchor.ts; 108 125 } 109 110 // Aligned timestamps which are used by the relaxed ready queue111 struct __attribute__((aligned(128))) __timestamp_t {112 volatile unsigned long long tv;113 };114 115 void ?{}(__timestamp_t & this) { this.tv = 0; }116 void ^?{}(__timestamp_t & this) {} -
libcfa/src/concurrency/stats.cfa
r299b8b28 rfc1347d0 68 68 } 69 69 70 static inline void tally_one( volatile uint64_t * agg, volatile uint64_t * val) { 71 uint64_t add = __atomic_exchange_n(val, 0_l64u, __ATOMIC_RELAXED); 72 __atomic_fetch_add(agg, add, __ATOMIC_RELAXED); 73 } 74 75 static inline void tally_one( volatile int64_t * agg, volatile int64_t * val) { 76 int64_t add = __atomic_exchange_n(val, 0_l64, __ATOMIC_RELAXED); 77 __atomic_fetch_add(agg, add, __ATOMIC_RELAXED); 78 } 79 70 80 void __tally_stats( struct __stats_t * cltr, struct __stats_t * proc ) { 71 __atomic_fetch_add( &cltr->ready.push.local.attempt, proc->ready.push.local.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.local.attempt = 0;72 __atomic_fetch_add( &cltr->ready.push.local.success, proc->ready.push.local.success, __ATOMIC_SEQ_CST ); proc->ready.push.local.success = 0;73 __atomic_fetch_add( &cltr->ready.push.share.attempt, proc->ready.push.share.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.share.attempt = 0;74 __atomic_fetch_add( &cltr->ready.push.share.success, proc->ready.push.share.success, __ATOMIC_SEQ_CST ); proc->ready.push.share.success = 0;75 __atomic_fetch_add( &cltr->ready.push.extrn.attempt, proc->ready.push.extrn.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.extrn.attempt = 0;76 __atomic_fetch_add( &cltr->ready.push.extrn.success, proc->ready.push.extrn.success, __ATOMIC_SEQ_CST ); proc->ready.push.extrn.success = 0;77 __atomic_fetch_add( &cltr->ready.pop.local .attempt, proc->ready.pop.local .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.local .attempt = 0;78 __atomic_fetch_add( &cltr->ready.pop.local .success, proc->ready.pop.local .success, __ATOMIC_SEQ_CST ); proc->ready.pop.local .success = 0;79 __atomic_fetch_add( &cltr->ready.pop.local .elock , proc->ready.pop.local .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.local .elock = 0;80 __atomic_fetch_add( &cltr->ready.pop.local .eempty , proc->ready.pop.local .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.local .eempty = 0;81 __atomic_fetch_add( &cltr->ready.pop.local .espec , proc->ready.pop.local .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.local .espec = 0;82 __atomic_fetch_add( &cltr->ready.pop.help .attempt, proc->ready.pop.help .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.help .attempt = 0;83 __atomic_fetch_add( &cltr->ready.pop.help .success, proc->ready.pop.help .success, __ATOMIC_SEQ_CST ); proc->ready.pop.help .success = 0;84 __atomic_fetch_add( &cltr->ready.pop.help .elock , proc->ready.pop.help .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.help .elock = 0;85 __atomic_fetch_add( &cltr->ready.pop.help .eempty , proc->ready.pop.help .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.help .eempty = 0;86 __atomic_fetch_add( &cltr->ready.pop.help .espec , proc->ready.pop.help .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.help .espec = 0;87 __atomic_fetch_add( &cltr->ready.pop.steal .attempt, proc->ready.pop.steal .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.steal .attempt = 0;88 __atomic_fetch_add( &cltr->ready.pop.steal .success, proc->ready.pop.steal .success, __ATOMIC_SEQ_CST ); proc->ready.pop.steal .success = 0;89 __atomic_fetch_add( &cltr->ready.pop.steal .elock , proc->ready.pop.steal .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .elock = 0;90 __atomic_fetch_add( &cltr->ready.pop.steal .eempty , proc->ready.pop.steal .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .eempty = 0;91 __atomic_fetch_add( &cltr->ready.pop.steal .espec , proc->ready.pop.steal .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .espec = 0;92 __atomic_fetch_add( &cltr->ready.pop.search.attempt, proc->ready.pop.search.attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.search.attempt = 0;93 __atomic_fetch_add( &cltr->ready.pop.search.success, proc->ready.pop.search.success, __ATOMIC_SEQ_CST ); proc->ready.pop.search.success = 0;94 __atomic_fetch_add( &cltr->ready.pop.search.elock , proc->ready.pop.search.elock , __ATOMIC_SEQ_CST ); proc->ready.pop.search.elock = 0;95 __atomic_fetch_add( &cltr->ready.pop.search.eempty , proc->ready.pop.search.eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.search.eempty = 0;96 __atomic_fetch_add( &cltr->ready.pop.search.espec , proc->ready.pop.search.espec , __ATOMIC_SEQ_CST ); proc->ready.pop.search.espec = 0;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;99 __atomic_fetch_add( &cltr->ready.threads.threads , proc->ready.threads.threads , __ATOMIC_SEQ_CST ); proc->ready.threads.threads = 0;100 __atomic_fetch_add( &cltr->ready.sleep.halts , proc->ready.sleep.halts , __ATOMIC_SEQ_CST ); proc->ready.sleep.halts = 0;101 __atomic_fetch_add( &cltr->ready.sleep.cancels , proc->ready.sleep.cancels , __ATOMIC_SEQ_CST ); proc->ready.sleep.cancels = 0;102 __atomic_fetch_add( &cltr->ready.sleep.wakes , proc->ready.sleep.wakes , __ATOMIC_SEQ_CST ); proc->ready.sleep.wakes = 0;103 __atomic_fetch_add( &cltr->ready.sleep.exits , proc->ready.sleep.exits , __ATOMIC_SEQ_CST ); proc->ready.sleep.exits = 0;81 tally_one( &cltr->ready.push.local.attempt, &proc->ready.push.local.attempt ); 82 tally_one( &cltr->ready.push.local.success, &proc->ready.push.local.success ); 83 tally_one( &cltr->ready.push.share.attempt, &proc->ready.push.share.attempt ); 84 tally_one( &cltr->ready.push.share.success, &proc->ready.push.share.success ); 85 tally_one( &cltr->ready.push.extrn.attempt, &proc->ready.push.extrn.attempt ); 86 tally_one( &cltr->ready.push.extrn.success, &proc->ready.push.extrn.success ); 87 tally_one( &cltr->ready.pop.local .attempt, &proc->ready.pop.local .attempt ); 88 tally_one( &cltr->ready.pop.local .success, &proc->ready.pop.local .success ); 89 tally_one( &cltr->ready.pop.local .elock , &proc->ready.pop.local .elock ); 90 tally_one( &cltr->ready.pop.local .eempty , &proc->ready.pop.local .eempty ); 91 tally_one( &cltr->ready.pop.local .espec , &proc->ready.pop.local .espec ); 92 tally_one( &cltr->ready.pop.help .attempt, &proc->ready.pop.help .attempt ); 93 tally_one( &cltr->ready.pop.help .success, &proc->ready.pop.help .success ); 94 tally_one( &cltr->ready.pop.help .elock , &proc->ready.pop.help .elock ); 95 tally_one( &cltr->ready.pop.help .eempty , &proc->ready.pop.help .eempty ); 96 tally_one( &cltr->ready.pop.help .espec , &proc->ready.pop.help .espec ); 97 tally_one( &cltr->ready.pop.steal .attempt, &proc->ready.pop.steal .attempt ); 98 tally_one( &cltr->ready.pop.steal .success, &proc->ready.pop.steal .success ); 99 tally_one( &cltr->ready.pop.steal .elock , &proc->ready.pop.steal .elock ); 100 tally_one( &cltr->ready.pop.steal .eempty , &proc->ready.pop.steal .eempty ); 101 tally_one( &cltr->ready.pop.steal .espec , &proc->ready.pop.steal .espec ); 102 tally_one( &cltr->ready.pop.search.attempt, &proc->ready.pop.search.attempt ); 103 tally_one( &cltr->ready.pop.search.success, &proc->ready.pop.search.success ); 104 tally_one( &cltr->ready.pop.search.elock , &proc->ready.pop.search.elock ); 105 tally_one( &cltr->ready.pop.search.eempty , &proc->ready.pop.search.eempty ); 106 tally_one( &cltr->ready.pop.search.espec , &proc->ready.pop.search.espec ); 107 tally_one( &cltr->ready.threads.migration , &proc->ready.threads.migration ); 108 tally_one( &cltr->ready.threads.extunpark , &proc->ready.threads.extunpark ); 109 tally_one( &cltr->ready.threads.threads , &proc->ready.threads.threads ); 110 tally_one( &cltr->ready.sleep.halts , &proc->ready.sleep.halts ); 111 tally_one( &cltr->ready.sleep.cancels , &proc->ready.sleep.cancels ); 112 tally_one( &cltr->ready.sleep.wakes , &proc->ready.sleep.wakes ); 113 tally_one( &cltr->ready.sleep.exits , &proc->ready.sleep.exits ); 104 114 105 115 #if defined(CFA_HAVE_LINUX_IO_URING_H) 106 __atomic_fetch_add( &cltr->io.alloc.fast , proc->io.alloc.fast , __ATOMIC_SEQ_CST ); proc->io.alloc.fast = 0;107 __atomic_fetch_add( &cltr->io.alloc.slow , proc->io.alloc.slow , __ATOMIC_SEQ_CST ); proc->io.alloc.slow = 0;108 __atomic_fetch_add( &cltr->io.alloc.fail , proc->io.alloc.fail , __ATOMIC_SEQ_CST ); proc->io.alloc.fail = 0;109 __atomic_fetch_add( &cltr->io.alloc.revoke , proc->io.alloc.revoke , __ATOMIC_SEQ_CST ); proc->io.alloc.revoke = 0;110 __atomic_fetch_add( &cltr->io.alloc.block , proc->io.alloc.block , __ATOMIC_SEQ_CST ); proc->io.alloc.block = 0;111 __atomic_fetch_add( &cltr->io.submit.fast , proc->io.submit.fast , __ATOMIC_SEQ_CST ); proc->io.submit.fast = 0;112 __atomic_fetch_add( &cltr->io.submit.slow , proc->io.submit.slow , __ATOMIC_SEQ_CST ); proc->io.submit.slow = 0;113 __atomic_fetch_add( &cltr->io.flush.external , proc->io.flush.external , __ATOMIC_SEQ_CST ); proc->io.flush.external = 0;114 __atomic_fetch_add( &cltr->io.calls.flush , proc->io.calls.flush , __ATOMIC_SEQ_CST ); proc->io.calls.flush = 0;115 __atomic_fetch_add( &cltr->io.calls.submitted , proc->io.calls.submitted , __ATOMIC_SEQ_CST ); proc->io.calls.submitted = 0;116 __atomic_fetch_add( &cltr->io.calls.drain , proc->io.calls.drain , __ATOMIC_SEQ_CST ); proc->io.calls.drain = 0;117 __atomic_fetch_add( &cltr->io.calls.completed , proc->io.calls.completed , __ATOMIC_SEQ_CST ); proc->io.calls.completed = 0;118 __atomic_fetch_add( &cltr->io.calls.errors.busy, proc->io.calls.errors.busy, __ATOMIC_SEQ_CST ); proc->io.calls.errors.busy = 0;119 __atomic_fetch_add( &cltr->io.poller.sleeps , proc->io.poller.sleeps , __ATOMIC_SEQ_CST ); proc->io.poller.sleeps = 0;116 tally_one( &cltr->io.alloc.fast , &proc->io.alloc.fast ); 117 tally_one( &cltr->io.alloc.slow , &proc->io.alloc.slow ); 118 tally_one( &cltr->io.alloc.fail , &proc->io.alloc.fail ); 119 tally_one( &cltr->io.alloc.revoke , &proc->io.alloc.revoke ); 120 tally_one( &cltr->io.alloc.block , &proc->io.alloc.block ); 121 tally_one( &cltr->io.submit.fast , &proc->io.submit.fast ); 122 tally_one( &cltr->io.submit.slow , &proc->io.submit.slow ); 123 tally_one( &cltr->io.flush.external , &proc->io.flush.external ); 124 tally_one( &cltr->io.calls.flush , &proc->io.calls.flush ); 125 tally_one( &cltr->io.calls.submitted , &proc->io.calls.submitted ); 126 tally_one( &cltr->io.calls.drain , &proc->io.calls.drain ); 127 tally_one( &cltr->io.calls.completed , &proc->io.calls.completed ); 128 tally_one( &cltr->io.calls.errors.busy, &proc->io.calls.errors.busy ); 129 tally_one( &cltr->io.poller.sleeps , &proc->io.poller.sleeps ); 120 130 #endif 121 131 } -
libcfa/src/containers/list.hfa
r299b8b28 rfc1347d0 18 18 #include <assert.h> 19 19 20 #define __DLISTED_MGD_COMMON(ELEM, NODE, LINKS_FLD) \ 21 static inline ELEM& $tempcv_n2e(NODE &node) { \ 22 return node; \ 23 } \ 24 \ 25 static inline NODE& $tempcv_e2n(ELEM &node) { \ 26 return ( NODE & ) node; \ 27 } \ 28 \ 29 static inline ELEM & ?`prev(NODE &node) { \ 30 $dlinks(ELEM) & ls = node.LINKS_FLD; \ 31 $mgd_link(ELEM) * l = &ls.prev; \ 32 ELEM * e = l->elem; \ 33 return *e; \ 34 } \ 35 \ 36 static inline ELEM & ?`next(NODE &node) { \ 37 $dlinks(ELEM) & ls = node.LINKS_FLD; \ 38 $mgd_link(ELEM) * l = &ls.next; \ 39 ELEM * e = l->elem; \ 40 return *e; \ 41 } \ 42 \ 43 static inline $mgd_link(ELEM) & $prev_link(NODE &node) { \ 44 $dlinks(ELEM) & ls = node.LINKS_FLD; \ 45 $mgd_link(ELEM) * l = &ls.prev; \ 46 return *l; \ 47 } \ 48 \ 49 static inline $mgd_link(ELEM) & $next_link(NODE &node) { \ 50 $dlinks(ELEM) & ls = node.LINKS_FLD; \ 51 $mgd_link(ELEM) * l = &ls.next; \ 52 return *l; \ 20 forall( Decorator &, T & ) 21 struct tytagref { 22 inline T &; 23 }; 24 25 trait embedded( tOuter &, tMid &, tInner & ) { 26 tytagref( tMid, tInner ) ?`inner( tOuter & ); 27 }; 28 29 // embedded is reflexive, with no info (void) as the type tag 30 forall (T &) 31 static inline tytagref(void, T) ?`inner ( T & this ) { tytagref( void, T ) ret = {this}; return ret; } 32 33 // use this on every case of plan-9 inheritance, to make embedded a closure of plan-9 inheritance 34 #define P9_EMBEDDED( derived, immedBase ) \ 35 forall( Tbase &, TdiscardPath & | { tytagref( TdiscardPath, Tbase ) ?`inner( immedBase & ); } ) \ 36 static inline tytagref(immedBase, Tbase) ?`inner( derived & this ) { \ 37 immedBase & ib = this; \ 38 Tbase & b = ib`inner; \ 39 tytagref(immedBase, Tbase) result = { b }; \ 40 return result; \ 41 } 42 43 #define EMBEDDED_VIA( OUTER, MID, INNER ) \ 44 (struct { tytagref(MID, INNER) ( * ?`inner ) ( OUTER & ); }){ ?`inner } 45 46 #define DLINK_VIA( TE, TLINK ) \ 47 EMBEDDED_VIA( TE, TLINK, dlink(TE) ) 48 49 50 // The origin is the position encountered at the start of iteration, 51 // signifying, "need to advance to the first element," and at the end 52 // of iteration, signifying, "no more elements." Normal comsumption of 53 // an iterator runs ?`moveNext as the first step, and uses the return 54 // of ?`moveNext as a guard, before dereferencing the iterator. So 55 // normal consumption of an iterator does not dereference an iterator 56 // in origin position. The value of a pointer (underlying a refence) 57 // that is exposed publicly as an iteraor, and also a pointer stored 58 // internally in a link field, is tagged, to indicate "is the origin" 59 // (internally, is the list-head sentinel node), or untagged, to indicate 60 // "is a regular node." Intent is to help a user who dereferences an 61 // iterator in origin position (which would be an API-use error on their 62 // part), by failing fast. 63 64 #if defined( __x86_64 ) 65 // Preferred case: tag in the most-significant bit. Dereference 66 // has been shown to segfault consistently. Maintenance should 67 // list more architectures as "ok" here, to let them use the 68 // preferred case, when valid. 69 #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 ) 70 #else 71 // Fallback case: tag in the least-significant bit. Dereference 72 // will often give an alignment error, but may not, e.g. if 73 // accessing a char-typed member. 32-bit x86 uses the most- 74 // significant bit for real room on the heap. 75 #define ORIGIN_TAG_BITNO 0 76 #endif 77 #define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO) 78 79 #define ORIGIN_TAG_SET(p) ((p) | ORIGIN_TAG_MASK) 80 #define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK) 81 #define ORIGIN_TAG_QUERY(p) ((p) & ORIGIN_TAG_MASK) 82 83 84 forall( tE & ) { 85 86 struct dlink{ 87 tE *next; 88 tE *prev; 89 }; 90 91 static inline void ?{}( dlink(tE) & this ) { 92 this.next = 0p; 93 this.prev = 0p; 94 } 95 96 forall( tLinks & = dlink(tE) ) 97 struct dlist { 98 inline dlink(tE); 99 }; 100 101 forall( tLinks & | embedded( tE, tLinks, dlink(tE) ) ) { 102 static inline tE * $get_list_origin_addr( dlist(tE, tLinks) & lst ) { 103 dlink(tE) & link_from_null = ( * (tE *) 0p )`inner; 104 ptrdiff_t link_offset = (ptrdiff_t) & link_from_null; 105 size_t origin_addr = ((size_t) & lst) - link_offset; 106 size_t preResult = ORIGIN_TAG_SET( origin_addr ); 107 return (tE *)preResult; 108 } 109 110 static inline void ?{}( dlist(tE, tLinks) & this ) { 111 tE * listOrigin = $get_list_origin_addr( this ); 112 ( ( dlink(tE) & ) this ){ listOrigin, listOrigin } ; 113 } 114 } 115 53 116 } 54 117 55 #define __DLISTED_MGD_JUSTEXPL(STRUCT, IN_THELIST, STRUCT_IN_THELIST) \ 56 struct STRUCT_IN_THELIST { \ 57 inline STRUCT; \ 58 }; \ 59 \ 60 void ?{}(STRUCT_IN_THELIST &) = void; \ 61 \ 62 static inline STRUCT_IN_THELIST& ?`IN_THELIST(STRUCT &this) { \ 63 return (STRUCT_IN_THELIST&)this; \ 64 } 65 66 #define __DLISTED_MGD_JUSTIMPL(STRUCT) 67 68 forall( tE & ) { 69 struct $mgd_link { 70 tE *elem; 71 void *terminator; 72 _Bool is_terminator; 73 // will collapse to single pointer with tag bit 74 }; 75 static inline void ?{}( $mgd_link(tE) &this, tE* elem ) { 76 (this.elem){ elem }; 77 (this.terminator){ 0p }; 78 (this.is_terminator){ 0 }; 79 } 80 static inline void ?{}( $mgd_link(tE) &this, void * terminator ) { 81 (this.elem){ 0p }; 82 (this.terminator){ terminator }; 83 (this.is_terminator){ 1 }; 84 } 85 static inline void ?=?( $mgd_link(tE) &this, tE* elem ) { 86 this.elem = elem ; 87 this.terminator = 0p; 88 this.is_terminator = 0; 89 } 90 static inline void ?=?( $mgd_link(tE) &this, void * terminator ) { 91 this.elem = 0p; 92 this.terminator = terminator; 93 this.is_terminator = 1; 94 } 95 struct $dlinks { 96 // containing item is not listed 97 // iff 98 // links have (elem == 0p && terminator == 0p) 99 $mgd_link(tE) next; 100 $mgd_link(tE) prev; 101 }; 102 static inline void ?{}( $dlinks(tE) &this ) { 103 (this.next){ (tE *)0p }; 104 (this.prev){ (tE *)0p }; 105 } 106 } 107 108 #define DLISTED_MGD_EXPL_IN(STRUCT, LIST_SUF) \ 109 $dlinks(STRUCT) $links_ ## LIST_SUF; 110 111 #define DLISTED_MGD_EXPL_OUT(STRUCT, LIST_SUF) \ 112 __DLISTED_MGD_JUSTEXPL(STRUCT, in_##LIST_SUF, STRUCT ## _in_ ## LIST_SUF) \ 113 __DLISTED_MGD_COMMON(STRUCT, STRUCT##_in_##LIST_SUF, $links_ ## LIST_SUF) 114 115 #define DLISTED_MGD_IMPL_IN(STRUCT) \ 116 $dlinks(STRUCT) $links; 117 118 #define DLISTED_MGD_IMPL_OUT(STRUCT) \ 119 __DLISTED_MGD_JUSTIMPL(STRUCT) \ 120 __DLISTED_MGD_COMMON(STRUCT, STRUCT, $links) 121 122 trait $dlistable(Tnode &, Telem &) { 123 $mgd_link(Telem) & $prev_link(Tnode &); 124 $mgd_link(Telem) & $next_link(Tnode &); 125 Telem& $tempcv_n2e(Tnode &); 126 Tnode& $tempcv_e2n(Telem &); 127 128 Telem& ?`next(Tnode &); 129 Telem& ?`prev(Tnode &); 130 }; 131 132 forall (Tnode &, Telem & | $dlistable(Tnode, Telem)) { 133 134 // implemented as a sentinel item in an underlying cicrular list 135 // theList.$links.next is first 136 // theList.$links.prev is last 137 // note this allocation preserves prev-next composition as an identity 138 struct dlist { 139 $dlinks(Telem) $links; 140 }; 141 142 // an empty dlist 143 // links refer to self, making a tight circle 144 static inline void ?{}( dlist(Tnode, Telem) & this ) { 145 $mgd_link(Telem) selfRef = (void *) &this; 146 ( this.$links ) { selfRef, selfRef }; 147 } 148 149 static inline Telem & ?`first( dlist(Tnode, Telem) &l ) { 150 return * l.$links.next.elem; 151 } 152 153 static inline Telem & ?`last( dlist(Tnode, Telem) &l ) { 154 return * l.$links.prev.elem; 155 } 156 157 #if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__)) 158 static bool $validate_fwd( dlist(Tnode, Telem) & this ) { 159 Tnode * it = & $tempcv_e2n( this`first ); 160 if (!it) return (& this`last == 0p); 161 162 while( $next_link(*it).elem ) { 163 it = & $tempcv_e2n( * $next_link(*it).elem ); 164 } 165 166 return ( it == & $tempcv_e2n( this`last ) ) && 167 ( $next_link(*it).is_terminator ) && 168 ( ((dlist(Tnode, Telem)*)$next_link(*it).terminator) == &this ); 169 } 170 static bool $validate_rev( dlist(Tnode, Telem) & this ) { 171 Tnode * it = & $tempcv_e2n( this`last ); 172 if (!it) return (& this`first == 0p); 173 174 while( $prev_link(*it).elem ) { 175 it = & $tempcv_e2n( * $prev_link(*it).elem ); 176 } 177 178 return ( it == & $tempcv_e2n( this`first ) ) && 179 ( $prev_link(*it).is_terminator ) && 180 ( ((dlist(Tnode, Telem)*)$prev_link(*it).terminator) == &this ); 181 } 182 static bool validate( dlist(Tnode, Telem) & this ) { 183 return $validate_fwd(this) && $validate_rev(this); 184 } 185 #endif 186 187 static inline void insert_after(Tnode &list_pos, Telem &to_insert) { 118 119 forall( tE &, tLinks & | embedded( tE, tLinks, dlink(tE) ) ) { 120 121 static inline void insert_after(tE & list_pos, tE &to_insert) { 188 122 verify (&list_pos != 0p); 189 123 verify (&to_insert != 0p); 190 Tnode &singleton_to_insert = $tempcv_e2n(to_insert); 191 verify($prev_link(singleton_to_insert).elem == 0p); 192 verify($next_link(singleton_to_insert).elem == 0p); 193 $prev_link(singleton_to_insert) = & $tempcv_n2e(list_pos); 194 $next_link(singleton_to_insert) = $next_link(list_pos); 195 if ($next_link(list_pos).is_terminator) { 196 dlist(Tnode, Telem) *list = ( dlist(Tnode, Telem) * ) $next_link(list_pos).terminator; 197 $dlinks(Telem) *list_links = & list->$links; 198 $mgd_link(Telem) *list_last = & list_links->prev; 199 *list_last = &to_insert; 200 } else { 201 Telem *list_pos_next = $next_link(list_pos).elem; 202 if (list_pos_next) { 203 Tnode & lpn_inlist = $tempcv_e2n(*list_pos_next); 204 $prev_link(lpn_inlist) = &to_insert; 205 } 206 } 207 $next_link(list_pos) = &to_insert; 208 } 209 210 static inline void insert_before(Tnode &list_pos, Telem &to_insert) { 124 dlink(tE) & linkToInsert = to_insert`inner; 125 verify(linkToInsert.prev == 0p); 126 verify(linkToInsert.next == 0p); 127 tE & list_pos_raw = list_pos; 128 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 129 dlink(tE) & list_pos_links = list_pos_elem`inner; 130 asm( "" : : : "memory" ); 131 tE & after_raw = * list_pos_links.next; 132 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 133 linkToInsert.prev = & list_pos_raw; 134 linkToInsert.next = & after_raw; 135 dlink(tE) & afterLinks = after_elem`inner; 136 afterLinks.prev = &to_insert; 137 list_pos_links.next = &to_insert; 138 asm( "" : : : "memory" ); 139 } 140 141 static inline void insert_before(tE & list_pos, tE &to_insert) { 211 142 verify (&list_pos != 0p); 212 143 verify (&to_insert != 0p); 213 Tnode &singleton_to_insert = $tempcv_e2n(to_insert); 214 verify($prev_link(singleton_to_insert).elem == 0p); 215 verify($next_link(singleton_to_insert).elem == 0p); 216 $next_link(singleton_to_insert) = & $tempcv_n2e(list_pos); 217 $prev_link(singleton_to_insert) = $prev_link(list_pos); 218 if ($prev_link(list_pos).is_terminator) { 219 dlist(Tnode, Telem) *list = ( dlist(Tnode, Telem) * ) $prev_link(list_pos).terminator; 220 $dlinks(Telem) *list_links = & list->$links; 221 $mgd_link(Telem) *list_first = & list_links->next; 222 *list_first = &to_insert; 223 } else { 224 Telem *list_pos_prev = $prev_link(list_pos).elem; 225 if (list_pos_prev) { 226 Tnode & lpp_inlist = $tempcv_e2n(*list_pos_prev); 227 $next_link(lpp_inlist) = &to_insert; 228 } 229 } 230 $prev_link(list_pos) = &to_insert; 231 } 232 233 static inline void insert_first(dlist(Tnode, Telem) &list, Telem &to_insert) { 234 verify (&list != 0p); 235 verify (&to_insert != 0p); 236 Tnode &singleton_to_insert = $tempcv_e2n(to_insert); 237 verify($prev_link(singleton_to_insert).elem == 0p); 238 verify($next_link(singleton_to_insert).elem == 0p); 239 240 $prev_link(singleton_to_insert) = (void*) &list; 241 $next_link(singleton_to_insert) = list.$links.next; 242 243 $dlinks(Telem) *listLinks = & list.$links; 244 if (listLinks->next.is_terminator) { 245 $mgd_link(Telem) * listPrevReference = & listLinks->prev; 246 *listPrevReference = &to_insert; 247 } else { 248 Tnode & next_inlist = $tempcv_e2n(*list.$links.next.elem); 249 $prev_link(next_inlist) = &to_insert; 250 } 251 $mgd_link(Telem) * listNextReference = & listLinks->next; 252 *listNextReference = &to_insert; 253 } 254 255 static inline void insert_last(dlist(Tnode, Telem) &list, Telem &to_insert) { 256 verify (&list != 0p); 257 verify (&to_insert != 0p); 258 Tnode &singleton_to_insert = $tempcv_e2n(to_insert); 259 verify($next_link(singleton_to_insert).elem == 0p); 260 verify($prev_link(singleton_to_insert).elem == 0p); 261 262 $next_link(singleton_to_insert) = (void*) &list; 263 $prev_link(singleton_to_insert) = list.$links.prev; 264 265 $dlinks(Telem) *listLinks = & list.$links; 266 if (listLinks->prev.is_terminator) { 267 $mgd_link(Telem) * listNextReference = & listLinks->next; 268 *listNextReference = &to_insert; 269 } else { 270 Tnode & prev_inlist = $tempcv_e2n(*list.$links.prev.elem); 271 $next_link(prev_inlist) = &to_insert; 272 } 273 $mgd_link(Telem) * listPrevReference = & listLinks->prev; 274 *listPrevReference = &to_insert; 275 } 276 277 static inline void remove(Tnode &list_pos) { 278 verify( &list_pos != 0p ); 279 280 $mgd_link(Telem) &incoming_from_prev = *0p; 281 $mgd_link(Telem) &incoming_from_next = *0p; 282 283 if ( $prev_link(list_pos).is_terminator ) { 284 dlist(Tnode, Telem) * tgt_before = ( dlist(Tnode, Telem) * ) $prev_link(list_pos).terminator; 285 $dlinks(Telem) * links_before = & tgt_before->$links; 286 &incoming_from_prev = & links_before->next; 287 } else if ($prev_link(list_pos).elem) { 288 Telem * tgt_before = $prev_link(list_pos).elem; 289 Tnode & list_pos_before = $tempcv_e2n(*tgt_before); 290 &incoming_from_prev = & $next_link(list_pos_before); 291 } 292 293 if ( $next_link(list_pos).is_terminator ) { 294 dlist(Tnode, Telem) * tgt_after = ( dlist(Tnode, Telem) * ) $next_link(list_pos).terminator; 295 $dlinks(Telem) * links_after = & tgt_after->$links; 296 &incoming_from_next = & links_after->prev; 297 } else if ($next_link(list_pos).elem) { 298 Telem * tgt_after = $next_link(list_pos).elem; 299 Tnode & list_pos_after = $tempcv_e2n(*tgt_after ); 300 &incoming_from_next = & $prev_link(list_pos_after ); 301 } 302 303 if (& incoming_from_prev) { 304 incoming_from_prev = $next_link(list_pos); 305 } 306 if (& incoming_from_next) { 307 incoming_from_next = $prev_link(list_pos); 308 } 309 310 $next_link(list_pos) = (Telem*) 0p; 311 $prev_link(list_pos) = (Telem*) 0p; 312 } 313 314 static inline bool ?`is_empty(dlist(Tnode, Telem) &list) { 315 verify( &list != 0p ); 316 $dlinks(Telem) *listLinks = & list.$links; 317 if (listLinks->next.is_terminator) { 318 verify(listLinks->prev.is_terminator); 319 verify(listLinks->next.terminator); 320 verify(listLinks->prev.terminator); 321 return true; 322 } else { 323 verify(!listLinks->prev.is_terminator); 324 verify(listLinks->next.elem); 325 verify(listLinks->prev.elem); 326 return false; 327 } 328 } 329 330 static inline Telem & pop_first(dlist(Tnode, Telem) &list) { 331 verify( &list != 0p ); 332 verify( !list`is_empty ); 333 $dlinks(Telem) *listLinks = & list.$links; 334 Telem & first = *listLinks->next.elem; 335 Tnode & list_pos_first = $tempcv_e2n( first ); 336 remove(list_pos_first); 337 return first; 338 } 339 340 static inline Telem & pop_last(dlist(Tnode, Telem) &list) { 341 verify( &list != 0p ); 342 verify( !list`is_empty ); 343 $dlinks(Telem) *listLinks = & list.$links; 344 Telem & last = *listLinks->prev.elem; 345 Tnode & list_pos_last = $tempcv_e2n( last ); 346 remove(list_pos_last); 347 return last; 348 } 144 dlink(tE) & linkToInsert = to_insert`inner; 145 verify(linkToInsert.next == 0p); 146 verify(linkToInsert.prev == 0p); 147 tE & list_pos_raw = list_pos; 148 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 149 dlink(tE) & list_pos_links = list_pos_elem`inner; 150 asm( "" : : : "memory" ); 151 tE & before_raw = * (list_pos_links).prev; 152 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 153 linkToInsert.next = & list_pos_raw; 154 linkToInsert.prev = & before_raw; 155 dlink(tE) & beforeLinks = before_elem`inner; 156 beforeLinks.next = &to_insert; 157 (list_pos_links).prev = &to_insert; 158 asm( "" : : : "memory" ); 159 } 160 161 static inline tE & remove(tE & list_pos) { 162 verify (&list_pos != 0p); 163 tE & list_pos_elem = list_pos; 164 verify( ! ORIGIN_TAG_QUERY((size_t) & list_pos_elem) ); 165 dlink(tE) & list_pos_links = list_pos_elem`inner; 166 tE & before_raw = * list_pos_links.prev; 167 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 168 dlink(tE) & before_links = before_elem`inner; 169 tE & after_raw = * list_pos_links.next; 170 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 171 dlink(tE) & after_links = after_elem`inner; 172 before_links.next = &after_raw; 173 after_links.prev = &before_raw; 174 asm( "" : : : "memory" ); 175 list_pos_links.prev = 0p; 176 list_pos_links.next = 0p; 177 asm( "" : : : "memory" ); 178 return list_pos_elem; 179 } 180 181 static inline tE & ?`first( dlist(tE, tLinks) &lst ) { 182 tE * firstPtr = lst.next; 183 if (ORIGIN_TAG_QUERY((size_t)firstPtr)) firstPtr = 0p; 184 return *firstPtr; 185 } 186 static inline tE & ?`last ( dlist(tE, tLinks) &lst ) { 187 tE * lastPtr = lst.prev; 188 if (ORIGIN_TAG_QUERY((size_t)lastPtr)) lastPtr = 0p; 189 return *lastPtr; 190 } 191 192 static inline bool ?`isEmpty( dlist(tE, tLinks) & lst ) { 193 tE * firstPtr = lst.next; 194 if (ORIGIN_TAG_QUERY((size_t)firstPtr)) firstPtr = 0p; 195 return firstPtr == 0p; 196 } 197 198 static inline tE & ?`elems( dlist(tE, tLinks) & lst ) { 199 tE * origin = $get_list_origin_addr( lst ); 200 return *origin; 201 } 202 203 static inline bool ?`moveNext( tE && refx ) { 204 tE && ref_inner = refx; 205 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 206 &ref_inner = oldReferent`inner.next; 207 return &ref_inner != 0p && 208 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 209 } 210 211 static inline bool ?`movePrev( tE && refx ) { 212 tE && ref_inner = refx; 213 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 214 &ref_inner = oldReferent`inner.prev; 215 return &ref_inner != 0p && 216 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 217 } 218 219 static inline bool ?`hasNext( tE & e ) { 220 return e`moveNext; 221 } 222 223 static inline bool ?`hasPrev( tE & e ) { 224 return e`movePrev; 225 } 226 227 static inline tE & ?`next( tE & e ) { 228 if( e`moveNext ) return e; 229 return * 0p; 230 } 231 232 static inline tE & ?`prev( tE & e ) { 233 if( e`movePrev ) return e; 234 return * 0p; 235 } 236 237 static inline void insert_first( dlist(tE, tLinks) &lst, tE & e ) { 238 insert_after(lst`elems, e); 239 } 240 241 static inline void insert_last( dlist(tE, tLinks) &lst, tE & e ) { 242 insert_before(lst`elems, e); 243 } 244 245 static inline tE & try_pop_front( dlist(tE, tLinks) &lst ) { 246 tE & first_inlist = lst`first; 247 tE & first_item = first_inlist; 248 if (&first_item) remove(first_inlist); 249 return first_item; 250 } 251 252 static inline tE & try_pop_back( dlist(tE, tLinks) &lst ) { 253 tE & last_inlist = lst`last; 254 tE & last_item = last_inlist; 255 if (&last_item) remove(last_inlist); 256 return last_item; 257 } 258 259 260 #if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__)) 261 static bool $validate_fwd( dlist(tE, tLinks) & this ) { 262 if ( ! & this`first ) return ( (& this`last) == 0p); 263 264 tE & lagElem = *0p; 265 266 while ( tE & it = this`elems; it`moveNext ) { 267 if (& lagElem == 0p && &it != & this`first ) return false; 268 & lagElem = & it; 269 } 270 271 if (& lagElem != & this`last) return false; 272 273 // TODO: verify that it is back at this`elems; 274 return true; 275 } 276 static bool $validate_rev( dlist(tE, tLinks) & this ) { 277 if ( ! & this`last ) return ( (& this`first) == 0p); 278 279 tE & lagElem = *0p; 280 281 while ( tE & it = this`elems; it`movePrev ) { 282 if (& lagElem == 0p && &it != & this`last ) return false; 283 & lagElem = & it; 284 } 285 286 if (& lagElem != & this`first) return false; 287 288 // TODO: verify that it is back at this`elems; 289 return true; 290 } 291 static bool validate( dlist(tE, tLinks) & this ) { 292 return $validate_fwd(this) && $validate_rev(this); 293 } 294 #endif 349 295 350 296 } -
libcfa/src/exception.hfa
r299b8b28 rfc1347d0 162 162 // Generate a new type-id value. 163 163 #define _EHM_TYPE_ID_VALUE(exception_name, arguments) \ 164 __attribute__(( section(".gnu.linkonce." "__cfatid_" #exception_name))) \164 __attribute__((cfa_linkonce)) \ 165 165 _EHM_TYPE_ID_TYPE(exception_name) arguments const \ 166 166 _EHM_TYPE_ID_NAME(exception_name) = { \ -
libcfa/src/executor.cfa
r299b8b28 rfc1347d0 7 7 #include <containers/list.hfa> 8 8 9 forall( T & | $dlistable(T, T) ) {9 forall( T &, TLink& = dlink(T) | embedded(T, TLink, dlink(T)) ) { 10 10 monitor Buffer { // unbounded buffer 11 dlist( T, T ) queue;// unbounded list of work requests11 dlist( T, TLink ) queue; // unbounded list of work requests 12 12 condition delay; 13 13 }; // Buffer 14 14 15 void insert( Buffer(T ) & mutex buf, T * elem ) with(buf) {16 dlist( T, T ) * qptr = &queue;// workaround https://cforall.uwaterloo.ca/trac/ticket/16615 void insert( Buffer(T, TLink) & mutex buf, T * elem ) with(buf) { 16 dlist( T, TLink ) * qptr = &queue; // workaround https://cforall.uwaterloo.ca/trac/ticket/166 17 17 insert_last( *qptr, *elem ); // insert element into buffer 18 18 signal( delay ); // restart 19 19 } // insert 20 20 21 T * remove( Buffer(T ) & mutex buf ) with(buf) {22 dlist( T, T ) * qptr = &queue;// workaround https://cforall.uwaterloo.ca/trac/ticket/16623 // if ( (*qptr)`is _empty ) wait( delay );// no request to process ? => wait24 if ( (*qptr)`is _empty ) return 0p;// no request to process ? => wait25 return & pop_first( *qptr );21 T * remove( Buffer(T, TLink) & mutex buf ) with(buf) { 22 dlist( T, TLink ) * qptr = &queue; // workaround https://cforall.uwaterloo.ca/trac/ticket/166 23 // if ( (*qptr)`isEmpty ) wait( delay ); // no request to process ? => wait 24 if ( (*qptr)`isEmpty ) return 0p; // no request to process ? => wait 25 return &try_pop_front( *qptr ); 26 26 } // remove 27 27 } // forall … … 29 29 struct WRequest { // client request, no return 30 30 void (* action)( void ); 31 DLISTED_MGD_IMPL_IN(WRequest)31 inline dlink(WRequest); 32 32 }; // WRequest 33 DLISTED_MGD_IMPL_OUT(WRequest)33 P9_EMBEDDED(WRequest, dlink(WRequest)) 34 34 35 35 void ?{}( WRequest & req ) with(req) { action = 0; } -
libcfa/src/heap.cfa
r299b8b28 rfc1347d0 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 20 21:20:48 202113 // Update Count : 103 312 // Last Modified On : Wed May 5 13:11:28 2021 13 // Update Count : 1035 14 14 // 15 15 … … 28 28 #include "bits/locks.hfa" // __spinlock_t 29 29 #include "startup.hfa" // STARTUP_PRIORITY_MEMORY 30 #include "math.hfa" // ceiling30 #include "math.hfa" // min 31 31 #include "bitmanip.hfa" // is_pow2, ceiling2 32 32 -
libcfa/src/iostream.cfa
r299b8b28 rfc1347d0 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 27 18:01:03202113 // Update Count : 13 3012 // Last Modified On : Sat May 15 09:39:21 2021 13 // Update Count : 1342 14 14 // 15 15 … … 659 659 int exp10, len2; \ 660 660 eng( f.val, f.pc, exp10 ); /* changes arguments */ \ 661 /* printf( "%g %d %d %d %s\n", f.val, f.wd, f.pc, exp10, format ); */ \ 661 662 if ( ! f.flags.left && f.wd > 1 ) { \ 662 /* Exponent size (number of digits, 'e', optional minus sign)*/ \663 f.wd -= lrint( floor( log10( abs( exp10 ) ) ) ) + 1 + 1 + (exp10 < 0 ? 1 : 0); \663 /* Exponent size: 'e', optional minus sign, number of digits: log10(0) => undefined */ \ 664 f.wd -= 1 + (exp10 < 0 ? 1 : 0) + lrint( floor( exp10 == 0 ? 0 : log10( abs( exp10 ) ) ) ) + 1; \ 664 665 if ( f.wd < 1 ) f.wd = 1; \ 665 666 } /* if */ \ … … 708 709 if ( ! f.flags.pc ) { /* no precision */ \ 709 710 fmtstr[sizeof(DFMTNP)-2] = f.base; /* sizeof includes '\0' */ \ 710 /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star] ); */ \711 /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star] ); */ \ 711 712 PrintWithDP2( os, &fmtstr[star], f.wd, f.val ) \ 712 713 } else { /* precision */ \ -
src/CodeGen/module.mk
r299b8b28 rfc1347d0 25 25 CodeGen/GenType.cc \ 26 26 CodeGen/GenType.h \ 27 CodeGen/LinkOnce.cc \ 28 CodeGen/LinkOnce.h \ 27 29 CodeGen/OperatorTable.cc \ 28 30 CodeGen/OperatorTable.h \ -
src/Concurrency/Keywords.cc
r299b8b28 rfc1347d0 432 432 new ObjectDecl( 433 433 Virtual::concurrentDefaultVTableName(), 434 Type::Const,434 noStorageClasses, 435 435 LinkageSpec::Cforall, 436 436 /* bitfieldWidth */ nullptr, … … 504 504 new ObjectDecl( 505 505 Virtual::concurrentDefaultVTableName(), 506 Type:: Const,506 Type::StorageClasses( Type::Extern ), 507 507 LinkageSpec::Cforall, 508 508 /* bitfieldWidth */ nullptr, -
src/InitTweak/InitTweak.cc
r299b8b28 rfc1347d0 1216 1216 1217 1217 void addDataSectonAttribute( ObjectDecl * objDecl ) { 1218 Type *strLitT = new PointerType( Type::Qualifiers( ), 1219 new BasicType( Type::Qualifiers( ), BasicType::Char ) ); 1220 std::list< Expression * > attr_params; 1221 attr_params.push_back( 1222 new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) ); 1223 objDecl->attributes.push_back(new Attribute("section", attr_params)); 1218 objDecl->attributes.push_back(new Attribute("section", { 1219 new ConstantExpr( Constant::from_string(".data#") ), 1220 })); 1224 1221 } 1225 1222 1226 1223 void addDataSectionAttribute( ast::ObjectDecl * objDecl ) { 1227 auto strLitT = new ast::PointerType(new ast::BasicType(ast::BasicType::Char)); 1228 objDecl->attributes.push_back(new ast::Attribute("section", {new ast::ConstantExpr(objDecl->location, strLitT, "\".data#\"", std::nullopt)})); 1224 objDecl->attributes.push_back(new ast::Attribute("section", { 1225 ast::ConstantExpr::from_string(objDecl->location, ".data#"), 1226 })); 1229 1227 } 1230 1228 -
src/Virtual/Tables.cc
r299b8b28 rfc1347d0 172 172 } 173 173 174 Attribute * linkonce( const std::string & subsection ) {175 const std::string section = ".gnu.linkonce." + subsection;176 return new Attribute( "section", {177 new ConstantExpr( Constant::from_string( section ) ),178 } );179 }180 181 174 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) { 182 175 assert( typeIdType ); … … 193 186 new AddressExpr( new NameExpr( "__cfatid_exception_t" ) ) 194 187 ) } ), 195 { linkonce( typeid_name) },188 { new Attribute( "cfa_linkonce", {} ) }, 196 189 noFuncSpecifiers 197 190 ); -
src/main.cc
r299b8b28 rfc1347d0 37 37 #include "CodeGen/FixNames.h" // for fixNames 38 38 #include "CodeGen/Generate.h" // for generate 39 #include "CodeGen/LinkOnce.h" // for translateLinkOnce 39 40 #include "CodeTools/DeclStats.h" // for printDeclStats 40 41 #include "CodeTools/ResolvProtoDump.h" // for dumpAsResolvProto … … 405 406 PASS( "Box", GenPoly::box( translationUnit ) ); 406 407 408 PASS( "Link-Once", CodeGen::translateLinkOnce( translationUnit ) ); 409 410 // Code has been lowered to C, now we can start generation. 411 407 412 if ( bcodegenp ) { 408 413 dump( translationUnit ); -
tests/Makefile.am
r299b8b28 rfc1347d0 67 67 .PHONY: list .validate 68 68 .INTERMEDIATE: .validate .validate.cfa 69 EXTRA_PROGRAMS = avl_test .dummy_hack # build but do not install69 EXTRA_PROGRAMS = avl_test linkonce .dummy_hack # build but do not install 70 70 EXTRA_DIST = test.py \ 71 71 pybin/__init__.py \ … … 94 94 95 95 avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa 96 linkonce_SOURCES = link-once/main.cfa link-once/partner.cfa 96 97 # automake doesn't know we still need C/CPP rules so pretend like we have a C program 97 98 nodist__dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp -
tests/array-container/array-md-sbscr-cases.cfa
r299b8b28 rfc1347d0 27 27 } 28 28 29 // Work around a compiler optimization that can lead to false failures. 30 // Think of `valExpected` as a constant local to each test function. 31 // When implemented that way, an optimization, run on some hardware, makes 32 // its value be off-by-a-little, compared with the values that have been 33 // stored-loaded (in the array under test). This effect has been observed 34 // on x86-32 with -O3. Declaring it as below forces the expected value 35 // to be stored-loaded too, which keeps the (admittedly lazily done) 36 // `assert(f1 == f2)` checks passing, when the intended <w,x,y,z> location 37 // is recovered, which is the point of all these tests. 38 volatile float valExpected = 0.0; 39 29 40 // Tests all the ways to split dimensions into CFA-supported chunks, by the only order that C supports: coarsest to finest stride. 30 41 forall( [Nw], [Nx], [Ny], [Nz] ) … … 36 47 ptrdiff_t iw = 2, ix = 3, iy=4, iz=5; 37 48 38 const float valExpected = getMagicNumber(iw, ix, iy, iz); 39 assert( wxyz[iw][ix][iy][iz] == valExpected ); 49 valExpected = getMagicNumber(iw, ix, iy, iz); 50 float valGot = wxyz[iw][ix][iy][iz]; 51 assert( valGot == valExpected ); 40 52 41 53 // order wxyz, natural split (4-0 or 0-4, no intermediate to declare) … … 86 98 ptrdiff_t iw = 2, ix = 3, iy=4, iz=5; 87 99 88 const floatvalExpected = getMagicNumber(iw, ix, iy, iz);100 valExpected = getMagicNumber(iw, ix, iy, iz); 89 101 assert( wxyz[iw][ix][iy][iz] == valExpected ); 90 102 … … 108 120 109 121 // order wxzy: wx*z, y 110 122 #if 0 123 // not working on 32-bit 111 124 assert(( wxyz[[iw , ix , all , iz ]][iy ] == valExpected )); 112 125 assert(( wxyz[[iw , ix , all , iz-1]][iy ] != valExpected )); 113 126 assert(( wxyz[[iw , ix , all , iz ]][iy-1] != valExpected )); 127 #endif 114 128 } 115 129 … … 127 141 ptrdiff_t iw = 2, ix = 3, iy=4, iz=5; 128 142 129 const floatvalExpected = getMagicNumber(iw, ix, iy, iz);143 valExpected = getMagicNumber(iw, ix, iy, iz); 130 144 assert( wxyz[iw][ix][iy][iz] == valExpected ); 131 145 … … 223 237 fillHelloData(wxyz); 224 238 225 const floatvalExpected = getMagicNumber(2, 3, 4, 5);239 valExpected = getMagicNumber(2, 3, 4, 5); 226 240 assert(( wxyz [2] [3] [4] [5] == valExpected )); 227 241 assert(( wxyz[[2, 3]][4] [5] == valExpected )); -
tests/list/.expect/dlist-insert-remove.txt
r299b8b28 rfc1347d0 1 ~~~~~~~~~~~~~~~~~ Headless List Tests - insert_after ~~~~~~~~~~~~~~~~2 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4 Test 1-i: Modifying Freds on MINE5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~6 ==== fred by MINE before7 3.148 -9 3.1410 -11 0.512 -13 0.514 -15 ==== fred by YOURS before16 3.1417 -18 3.1419 -20 0.521 -22 0.523 -24 ==== fred by MINE after25 3.1426 0.527 -28 3.1429 -30 0.531 -32 0.533 3.1434 -35 ==== fred by YOURS after36 3.1437 -38 3.1439 -40 0.541 -42 0.543 -44 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~45 Test 2-i. Modifying Freds on YOURS46 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~47 ==== fred by MINE before48 3.1449 -50 3.1451 -52 0.553 -54 0.555 -56 ==== fred by YOURS before57 3.1458 -59 3.1460 -61 0.562 -63 0.564 -65 ==== fred by MINE after66 3.1467 -68 3.1469 -70 0.571 -72 0.573 -74 ==== fred by YOURS after75 3.1476 0.577 -78 3.1479 -80 0.581 -82 0.583 3.1484 -85 ~~~~~~~~~~~~~~~~~~~~~~~~~~~86 Test 3-i. Modifying Maries87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~88 ==== mary before89 3.1490 -91 3.1492 -93 0.594 -95 0.596 -97 ==== mary after98 3.1499 0.5100 -101 3.14102 -103 0.5104 -105 0.5106 3.14107 -108 109 ~~~~~~~~~~~~~~~~ Headless List Tests - insert_before ~~~~~~~~~~~~~~~~110 111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~112 Test 1-ii: Modifying Freds on MINE113 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~114 ==== fred by MINE before115 3.14116 -117 3.14118 -119 0.5120 -121 0.5122 -123 ==== fred by YOURS before124 3.14125 -126 3.14127 -128 0.5129 -130 0.5131 -132 ==== fred by MINE after133 3.14134 0.5135 -136 3.14137 -138 0.5139 -140 0.5141 3.14142 -143 ==== fred by YOURS after144 3.14145 -146 3.14147 -148 0.5149 -150 0.5151 -152 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~153 Test 2-ii. Modifying Freds on YOURS154 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~155 ==== fred by MINE before156 3.14157 -158 3.14159 -160 0.5161 -162 0.5163 -164 ==== fred by YOURS before165 3.14166 -167 3.14168 -169 0.5170 -171 0.5172 -173 ==== fred by MINE after174 3.14175 -176 3.14177 -178 0.5179 -180 0.5181 -182 ==== fred by YOURS after183 3.14184 0.5185 -186 3.14187 -188 0.5189 -190 0.5191 3.14192 -193 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~194 Test 3-ii. Modifying Maries195 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~196 ==== mary before197 3.14198 -199 3.14200 -201 0.5202 -203 0.5204 -205 ==== mary after206 3.14207 0.5208 -209 3.14210 -211 0.5212 -213 0.5214 3.14215 -216 1 217 2 ~~~~~~~~~~~~~~~~~ Headed List Tests - insert_first ~~~~~~~~~~~~~~~~~~ … … 557 342 - 558 343 559 ~~~~~~~~~~ Element removal tests on Head less List: mid~~~~~~~~~~560 561 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 562 Test 1 0-i. Modifying Freds on MINE563 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 ==== fred by MINE before 565 1.7 566 2.7 567 3.7 568 - 569 1.7 570 - 571 3.7 572 - 573 3.7 574 2.7 575 1.7 576 - 577 ==== fred by YOURS before 578 1.7 579 2.7 580 3.7 581 - 582 1.7 583 - 584 3.7 585 - 586 3.7 587 2.7 588 1.7 589 - 590 ==== fred by MINE after 591 1.7592 3.7 593 - 594 1.7595 - 596 3.7 597 - 598 3.7 599 1.7600 - 601 ==== fred by YOURS after 602 1.7 603 2.7 604 3.7 605 - 606 1.7 607 - 608 3.7 609 - 610 3.7 611 2.7 612 1.7 613 - 614 ==== fred by MINE after 615 2.7616 - 617 2.7618 - 619 - 620 - 621 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~622 Test 1 1-i. Modifying Freds on YOURS623 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~624 ==== fred by MINE before 625 1.7 626 2.7 627 3.7 628 - 629 1.7 630 - 631 3.7 632 - 633 3.7 634 2.7 635 1.7 636 - 637 ==== fred by YOURS before 638 1.7 639 2.7 640 3.7 641 - 642 1.7 643 - 644 3.7 645 - 646 3.7 647 2.7 648 1.7 649 - 650 ==== fred by MINE after 651 1.7 652 2.7 653 3.7 654 - 655 1.7 656 - 657 3.7 658 - 659 3.7 660 2.7 661 1.7 662 - 663 ==== fred by YOURS after 664 1.7665 3.7 666 - 667 1.7668 - 669 3.7 670 - 671 3.7 672 1.7673 - 674 ==== fred by YOURS after 675 2.7676 - 677 2.7678 - 679 - 680 - 681 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 682 Test 1 2-i. Modifying Maries683 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 344 ~~~~~~~~~~ Element removal tests on Headed List: at first ~~~~~~~~~~ 345 346 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 347 Test 13-i. Modifying Freds on MINE 348 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 349 ==== fred by MINE before 350 1.7 351 2.7 352 3.7 353 - 354 1.7 355 - 356 3.7 357 - 358 3.7 359 2.7 360 1.7 361 - 362 ==== fred by YOURS before 363 1.7 364 2.7 365 3.7 366 - 367 1.7 368 - 369 3.7 370 - 371 3.7 372 2.7 373 1.7 374 - 375 ==== fred by MINE after 376 2.7 377 3.7 378 - 379 2.7 380 - 381 3.7 382 - 383 3.7 384 2.7 385 - 386 ==== fred by YOURS after 387 1.7 388 2.7 389 3.7 390 - 391 1.7 392 - 393 3.7 394 - 395 3.7 396 2.7 397 1.7 398 - 399 ==== fred by MINE after 400 1.7 401 - 402 1.7 403 - 404 - 405 - 406 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 407 Test 14-i. Modifying Freds on YOURS 408 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 409 ==== fred by MINE before 410 1.7 411 2.7 412 3.7 413 - 414 1.7 415 - 416 3.7 417 - 418 3.7 419 2.7 420 1.7 421 - 422 ==== fred by YOURS before 423 1.7 424 2.7 425 3.7 426 - 427 1.7 428 - 429 3.7 430 - 431 3.7 432 2.7 433 1.7 434 - 435 ==== fred by MINE after 436 1.7 437 2.7 438 3.7 439 - 440 1.7 441 - 442 3.7 443 - 444 3.7 445 2.7 446 1.7 447 - 448 ==== fred by YOURS after 449 2.7 450 3.7 451 - 452 2.7 453 - 454 3.7 455 - 456 3.7 457 2.7 458 - 459 ==== fred by YOURS after 460 1.7 461 - 462 1.7 463 - 464 - 465 - 466 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 Test 15-i. Modifying Maries 468 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 469 ==== mary before 685 470 1.7 … … 696 481 - 697 482 ==== mary after 698 1.7699 3.7 700 - 701 1.7702 - 703 3.7 704 - 705 3.7 706 1.7707 - 708 ==== mary after 709 2.7710 - 711 2.7712 - 713 - 714 - 715 716 ~~~~~~~~~~ Element removal tests on Head less List: at first ~~~~~~~~~~717 718 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 Test 1 0-ii. Modifying Freds on MINE720 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 721 ==== fred by MINE before 722 1.7 723 2.7 724 3.7 725 - 726 1.7 727 - 728 3.7 729 - 730 3.7 731 2.7 732 1.7 733 - 734 ==== fred by YOURS before 735 1.7 736 2.7 737 3.7 738 - 739 1.7 740 - 741 3.7 742 - 743 3.7 744 2.7 745 1.7 746 - 747 ==== fred by MINE after 748 2.7749 3.7750 - 751 2.7752 - 753 3.7754 - 755 3.7756 2.7757 - 758 ==== fred by YOURS after 759 1.7 760 2.7 761 3.7 762 - 763 1.7 764 - 765 3.7 766 - 767 3.7 768 2.7 769 1.7 770 - 771 ==== fred by MINE after 772 1.7773 - 774 1.7775 - 776 - 777 - 778 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~779 Test 1 1-ii. Modifying Freds on YOURS780 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~781 ==== fred by MINE before 782 1.7 783 2.7 784 3.7 785 - 786 1.7 787 - 788 3.7 789 - 790 3.7 791 2.7 792 1.7 793 - 794 ==== fred by YOURS before 795 1.7 796 2.7 797 3.7 798 - 799 1.7 800 - 801 3.7 802 - 803 3.7 804 2.7 805 1.7 806 - 807 ==== fred by MINE after 808 1.7 809 2.7 810 3.7 811 - 812 1.7 813 - 814 3.7 815 - 816 3.7 817 2.7 818 1.7 819 - 820 ==== fred by YOURS after 821 2.7822 3.7823 - 824 2.7825 - 826 3.7827 - 828 3.7829 2.7830 - 831 ==== fred by YOURS after 832 1.7833 - 834 1.7835 - 836 - 837 - 838 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 839 Test 1 2-ii. Modifying Maries840 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 483 2.7 484 3.7 485 - 486 2.7 487 - 488 3.7 489 - 490 3.7 491 2.7 492 - 493 ==== mary after 494 1.7 495 - 496 1.7 497 - 498 - 499 - 500 501 ~~~~~~~~~~ Element removal tests on Headed List: at last ~~~~~~~~~~ 502 503 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 504 Test 13-ii. Modifying Freds on MINE 505 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 ==== fred by MINE before 507 1.7 508 2.7 509 3.7 510 - 511 1.7 512 - 513 3.7 514 - 515 3.7 516 2.7 517 1.7 518 - 519 ==== fred by YOURS before 520 1.7 521 2.7 522 3.7 523 - 524 1.7 525 - 526 3.7 527 - 528 3.7 529 2.7 530 1.7 531 - 532 ==== fred by MINE after 533 1.7 534 2.7 535 - 536 1.7 537 - 538 2.7 539 - 540 2.7 541 1.7 542 - 543 ==== fred by YOURS after 544 1.7 545 2.7 546 3.7 547 - 548 1.7 549 - 550 3.7 551 - 552 3.7 553 2.7 554 1.7 555 - 556 ==== fred by MINE after 557 3.7 558 - 559 3.7 560 - 561 - 562 - 563 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 Test 14-ii. Modifying Freds on YOURS 565 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 566 ==== fred by MINE before 567 1.7 568 2.7 569 3.7 570 - 571 1.7 572 - 573 3.7 574 - 575 3.7 576 2.7 577 1.7 578 - 579 ==== fred by YOURS before 580 1.7 581 2.7 582 3.7 583 - 584 1.7 585 - 586 3.7 587 - 588 3.7 589 2.7 590 1.7 591 - 592 ==== fred by MINE after 593 1.7 594 2.7 595 3.7 596 - 597 1.7 598 - 599 3.7 600 - 601 3.7 602 2.7 603 1.7 604 - 605 ==== fred by YOURS after 606 1.7 607 2.7 608 - 609 1.7 610 - 611 2.7 612 - 613 2.7 614 1.7 615 - 616 ==== fred by YOURS after 617 3.7 618 - 619 3.7 620 - 621 - 622 - 623 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 624 Test 15-ii. Modifying Maries 625 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 626 ==== mary before 842 627 1.7 … … 853 638 - 854 639 ==== mary after 855 2.7 856 3.7 857 - 858 2.7 859 - 860 3.7 861 - 862 3.7 863 2.7 864 - 865 ==== mary after 866 1.7 867 - 868 1.7 869 - 870 - 871 - 872 873 ~~~~~~~~~~ Element removal tests on Headless List: at last ~~~~~~~~~~ 874 875 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 876 Test 10-iii. Modifying Freds on MINE 877 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 ==== fred by MINE before 879 1.7 880 2.7 881 3.7 882 - 883 1.7 884 - 885 3.7 886 - 887 3.7 888 2.7 889 1.7 890 - 891 ==== fred by YOURS before 892 1.7 893 2.7 894 3.7 895 - 896 1.7 897 - 898 3.7 899 - 900 3.7 901 2.7 902 1.7 903 - 904 ==== fred by MINE after 905 1.7 906 2.7 907 - 908 1.7 909 - 910 2.7 911 - 912 2.7 913 1.7 914 - 915 ==== fred by YOURS after 916 1.7 917 2.7 918 3.7 919 - 920 1.7 921 - 922 3.7 923 - 924 3.7 925 2.7 926 1.7 927 - 928 ==== fred by MINE after 929 3.7 930 - 931 3.7 932 - 933 - 934 - 935 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 936 Test 11-iii. Modifying Freds on YOURS 937 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 938 ==== fred by MINE before 939 1.7 940 2.7 941 3.7 942 - 943 1.7 944 - 945 3.7 946 - 947 3.7 948 2.7 949 1.7 950 - 951 ==== fred by YOURS before 952 1.7 953 2.7 954 3.7 955 - 956 1.7 957 - 958 3.7 959 - 960 3.7 961 2.7 962 1.7 963 - 964 ==== fred by MINE after 965 1.7 966 2.7 967 3.7 968 - 969 1.7 970 - 971 3.7 972 - 973 3.7 974 2.7 975 1.7 976 - 977 ==== fred by YOURS after 978 1.7 979 2.7 980 - 981 1.7 982 - 983 2.7 984 - 985 2.7 986 1.7 987 - 988 ==== fred by YOURS after 989 3.7 990 - 991 3.7 992 - 993 - 994 - 995 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 996 Test 12-iii. Modifying Maries 997 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 640 1.7 641 2.7 642 - 643 1.7 644 - 645 2.7 646 - 647 2.7 648 1.7 649 - 650 ==== mary after 651 3.7 652 - 653 3.7 654 - 655 - 656 - 657 658 ~~~~~~~~~~ Element removal tests on Headed List: of sole ~~~~~~~~~~ 659 660 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 661 Test 13-iii. Modifying Freds on MINE 662 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 663 ==== fred by MINE before 664 0.7 665 - 666 0.7 667 - 668 0.7 669 - 670 0.7 671 - 672 ==== fred by YOURS before 673 0.7 674 - 675 0.7 676 - 677 0.7 678 - 679 0.7 680 - 681 ==== fred by YOURS after 682 0.7 683 - 684 0.7 685 - 686 0.7 687 - 688 0.7 689 - 690 ==== fred by MINE after 691 0.7 692 - 693 0.7 694 - 695 - 696 - 697 ==== fred by MINE after 698 0.7 699 - 700 0.7 701 - 702 0.7 703 - 704 0.7 705 - 706 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 707 Test 14-iii. Modifying Freds on YOURS 708 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 709 ==== fred by MINE before 710 0.7 711 - 712 0.7 713 - 714 0.7 715 - 716 0.7 717 - 718 ==== fred by YOURS before 719 0.7 720 - 721 0.7 722 - 723 0.7 724 - 725 0.7 726 - 727 ==== fred by YOURS after 728 0.7 729 - 730 0.7 731 - 732 0.7 733 - 734 0.7 735 - 736 ==== fred by YOURS after 737 0.7 738 - 739 0.7 740 - 741 - 742 - 743 ==== fred by YOURS after 744 0.7 745 - 746 0.7 747 - 748 0.7 749 - 750 0.7 751 - 752 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 753 Test 15-iii. Modifying Maries 754 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 998 755 ==== mary before 999 1.7 1000 2.7 1001 3.7 1002 - 1003 1.7 1004 - 1005 3.7 1006 - 1007 3.7 1008 2.7 1009 1.7 1010 - 1011 ==== mary after 1012 1.7 1013 2.7 1014 - 1015 1.7 1016 - 1017 2.7 1018 - 1019 2.7 1020 1.7 1021 - 1022 ==== mary after 1023 3.7 1024 - 1025 3.7 1026 - 1027 - 1028 - 1029 1030 ~~~~~~~~~~ Element removal tests on Headed List: at first ~~~~~~~~~~ 1031 1032 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1033 Test 13-i. Modifying Freds on MINE 1034 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1035 ==== fred by MINE before 1036 1.7 1037 2.7 1038 3.7 1039 - 1040 1.7 1041 - 1042 3.7 1043 - 1044 3.7 1045 2.7 1046 1.7 1047 - 1048 ==== fred by YOURS before 1049 1.7 1050 2.7 1051 3.7 1052 - 1053 1.7 1054 - 1055 3.7 1056 - 1057 3.7 1058 2.7 1059 1.7 1060 - 1061 ==== fred by MINE after 1062 2.7 1063 3.7 1064 - 1065 2.7 1066 - 1067 3.7 1068 - 1069 3.7 1070 2.7 1071 - 1072 ==== fred by YOURS after 1073 1.7 1074 2.7 1075 3.7 1076 - 1077 1.7 1078 - 1079 3.7 1080 - 1081 3.7 1082 2.7 1083 1.7 1084 - 1085 ==== fred by MINE after 1086 1.7 1087 - 1088 1.7 1089 - 1090 - 1091 - 1092 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1093 Test 14-i. Modifying Freds on YOURS 1094 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1095 ==== fred by MINE before 1096 1.7 1097 2.7 1098 3.7 1099 - 1100 1.7 1101 - 1102 3.7 1103 - 1104 3.7 1105 2.7 1106 1.7 1107 - 1108 ==== fred by YOURS before 1109 1.7 1110 2.7 1111 3.7 1112 - 1113 1.7 1114 - 1115 3.7 1116 - 1117 3.7 1118 2.7 1119 1.7 1120 - 1121 ==== fred by MINE after 1122 1.7 1123 2.7 1124 3.7 1125 - 1126 1.7 1127 - 1128 3.7 1129 - 1130 3.7 1131 2.7 1132 1.7 1133 - 1134 ==== fred by YOURS after 1135 2.7 1136 3.7 1137 - 1138 2.7 1139 - 1140 3.7 1141 - 1142 3.7 1143 2.7 1144 - 1145 ==== fred by YOURS after 1146 1.7 1147 - 1148 1.7 1149 - 1150 - 1151 - 1152 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1153 Test 15-i. Modifying Maries 756 0.7 757 - 758 0.7 759 - 760 0.7 761 - 762 0.7 763 - 764 ==== mary after 765 0.7 766 - 767 0.7 768 - 769 - 770 - 771 ==== mary after 772 0.7 773 - 774 0.7 775 - 776 0.7 777 - 778 0.7 779 - 780 781 ~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~ 782 783 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 784 Test 16-i. Modifying Freds on MINE 785 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 ==== fred by MINE before 787 1.7 788 2.7 789 3.7 790 - 791 1.7 792 - 793 3.7 794 - 795 3.7 796 2.7 797 1.7 798 - 799 ==== fred by YOURS before 800 1.7 801 2.7 802 3.7 803 - 804 1.7 805 - 806 3.7 807 - 808 3.7 809 2.7 810 1.7 811 - 812 ==== fred by MINE after 813 2.7 814 3.7 815 - 816 2.7 817 - 818 3.7 819 - 820 3.7 821 2.7 822 - 823 ==== fred by YOURS after 824 1.7 825 2.7 826 3.7 827 - 828 1.7 829 - 830 3.7 831 - 832 3.7 833 2.7 834 1.7 835 - 836 ==== fred by MINE after 837 1.7 838 - 839 1.7 840 - 841 - 842 - 843 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 844 Test 16-ii. Modifying Freds on YOURS 845 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 846 ==== fred by MINE before 847 1.7 848 2.7 849 3.7 850 - 851 1.7 852 - 853 3.7 854 - 855 3.7 856 2.7 857 1.7 858 - 859 ==== fred by YOURS before 860 1.7 861 2.7 862 3.7 863 - 864 1.7 865 - 866 3.7 867 - 868 3.7 869 2.7 870 1.7 871 - 872 ==== fred by MINE after 873 1.7 874 2.7 875 3.7 876 - 877 1.7 878 - 879 3.7 880 - 881 3.7 882 2.7 883 1.7 884 - 885 ==== fred by YOURS after 886 2.7 887 3.7 888 - 889 2.7 890 - 891 3.7 892 - 893 3.7 894 2.7 895 - 896 ==== fred by YOURS after 897 1.7 898 - 899 1.7 900 - 901 - 902 - 903 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 904 Test 16-iii. Modifying Maries 1154 905 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1155 906 ==== mary before … … 1185 936 - 1186 937 1187 ~~~~~~~~~~ E lement removal tests on Headed List: at last ~~~~~~~~~~1188 1189 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1190 Test 1 3-ii. Modifying Freds on MINE1191 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1192 ==== fred by MINE before 1193 1.7 1194 2.7 1195 3.7 1196 - 1197 1.7 1198 - 1199 3.7 1200 - 1201 3.7 1202 2.7 1203 1.7 1204 - 1205 ==== fred by YOURS before 1206 1.7 1207 2.7 1208 3.7 1209 - 1210 1.7 1211 - 1212 3.7 1213 - 1214 3.7 1215 2.7 1216 1.7 1217 - 1218 ==== fred by MINE after 1219 1.7 1220 2.7 1221 - 1222 1.7 1223 - 1224 2.7 1225 - 1226 2.7 1227 1.7 1228 - 1229 ==== fred by YOURS after 1230 1.7 1231 2.7 1232 3.7 1233 - 1234 1.7 1235 - 1236 3.7 1237 - 1238 3.7 1239 2.7 1240 1.7 1241 - 1242 ==== fred by MINE after 1243 3.7 1244 - 1245 3.7 1246 - 1247 - 1248 - 1249 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1250 Test 1 4-ii. Modifying Freds on YOURS1251 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1252 ==== fred by MINE before 1253 1.7 1254 2.7 1255 3.7 1256 - 1257 1.7 1258 - 1259 3.7 1260 - 1261 3.7 1262 2.7 1263 1.7 1264 - 1265 ==== fred by YOURS before 1266 1.7 1267 2.7 1268 3.7 1269 - 1270 1.7 1271 - 1272 3.7 1273 - 1274 3.7 1275 2.7 1276 1.7 1277 - 1278 ==== fred by MINE after 1279 1.7 1280 2.7 1281 3.7 1282 - 1283 1.7 1284 - 1285 3.7 1286 - 1287 3.7 1288 2.7 1289 1.7 1290 - 1291 ==== fred by YOURS after 1292 1.7 1293 2.7 1294 - 1295 1.7 1296 - 1297 2.7 1298 - 1299 2.7 1300 1.7 1301 - 1302 ==== fred by YOURS after 1303 3.7 1304 - 1305 3.7 1306 - 1307 - 1308 - 1309 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1310 Test 1 5-ii. Modifying Maries938 ~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~ 939 940 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 941 Test 17-i. Modifying Freds on MINE 942 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 943 ==== fred by MINE before 944 1.7 945 2.7 946 3.7 947 - 948 1.7 949 - 950 3.7 951 - 952 3.7 953 2.7 954 1.7 955 - 956 ==== fred by YOURS before 957 1.7 958 2.7 959 3.7 960 - 961 1.7 962 - 963 3.7 964 - 965 3.7 966 2.7 967 1.7 968 - 969 ==== fred by MINE after 970 1.7 971 2.7 972 - 973 1.7 974 - 975 2.7 976 - 977 2.7 978 1.7 979 - 980 ==== fred by YOURS after 981 1.7 982 2.7 983 3.7 984 - 985 1.7 986 - 987 3.7 988 - 989 3.7 990 2.7 991 1.7 992 - 993 ==== fred by MINE after 994 3.7 995 - 996 3.7 997 - 998 - 999 - 1000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1001 Test 17-ii. Modifying Freds on YOURS 1002 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1003 ==== fred by MINE before 1004 1.7 1005 2.7 1006 3.7 1007 - 1008 1.7 1009 - 1010 3.7 1011 - 1012 3.7 1013 2.7 1014 1.7 1015 - 1016 ==== fred by YOURS before 1017 1.7 1018 2.7 1019 3.7 1020 - 1021 1.7 1022 - 1023 3.7 1024 - 1025 3.7 1026 2.7 1027 1.7 1028 - 1029 ==== fred by MINE after 1030 1.7 1031 2.7 1032 3.7 1033 - 1034 1.7 1035 - 1036 3.7 1037 - 1038 3.7 1039 2.7 1040 1.7 1041 - 1042 ==== fred by YOURS after 1043 1.7 1044 2.7 1045 - 1046 1.7 1047 - 1048 2.7 1049 - 1050 2.7 1051 1.7 1052 - 1053 ==== fred by YOURS after 1054 3.7 1055 - 1056 3.7 1057 - 1058 - 1059 - 1060 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1061 Test 17-iii. Modifying Maries 1311 1062 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1312 1063 ==== mary before … … 1342 1093 - 1343 1094 1344 ~~~~~~~~~~ Element removal tests on Headed List: of sole ~~~~~~~~~~ 1345 1346 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1347 Test 13-iii. Modifying Freds on MINE 1348 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1349 ==== fred by MINE before 1350 0.7 1351 - 1352 0.7 1353 - 1354 0.7 1355 - 1356 0.7 1357 - 1358 ==== fred by YOURS before 1359 0.7 1360 - 1361 0.7 1362 - 1363 0.7 1364 - 1365 0.7 1366 - 1367 ==== fred by YOURS after 1368 0.7 1369 - 1370 0.7 1371 - 1372 0.7 1373 - 1374 0.7 1375 - 1376 ==== fred by MINE after 1377 0.7 1378 - 1379 0.7 1380 - 1381 - 1382 - 1383 ==== fred by MINE after 1384 0.7 1385 - 1386 0.7 1387 - 1388 0.7 1389 - 1390 0.7 1391 - 1392 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1393 Test 14-iii. Modifying Freds on YOURS 1394 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1395 ==== fred by MINE before 1396 0.7 1397 - 1398 0.7 1399 - 1400 0.7 1401 - 1402 0.7 1403 - 1404 ==== fred by YOURS before 1405 0.7 1406 - 1407 0.7 1408 - 1409 0.7 1410 - 1411 0.7 1412 - 1413 ==== fred by YOURS after 1414 0.7 1415 - 1416 0.7 1417 - 1418 0.7 1419 - 1420 0.7 1421 - 1422 ==== fred by YOURS after 1423 0.7 1424 - 1425 0.7 1426 - 1427 - 1428 - 1429 ==== fred by YOURS after 1430 0.7 1431 - 1432 0.7 1433 - 1434 0.7 1435 - 1436 0.7 1437 - 1438 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1439 Test 15-iii. Modifying Maries 1440 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1441 ==== mary before 1442 0.7 1443 - 1444 0.7 1445 - 1446 0.7 1447 - 1448 0.7 1449 - 1450 ==== mary after 1451 0.7 1452 - 1453 0.7 1454 - 1455 - 1456 - 1457 ==== mary after 1458 0.7 1459 - 1460 0.7 1461 - 1462 0.7 1463 - 1464 0.7 1465 - 1466 1467 ~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~ 1468 1469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1470 Test 16-i. Modifying Freds on MINE 1471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1472 ==== fred by MINE before 1473 1.7 1474 2.7 1475 3.7 1476 - 1477 1.7 1478 - 1479 3.7 1480 - 1481 3.7 1482 2.7 1483 1.7 1484 - 1485 ==== fred by YOURS before 1486 1.7 1487 2.7 1488 3.7 1489 - 1490 1.7 1491 - 1492 3.7 1493 - 1494 3.7 1495 2.7 1496 1.7 1497 - 1498 ==== fred by MINE after 1499 2.7 1500 3.7 1501 - 1502 2.7 1503 - 1504 3.7 1505 - 1506 3.7 1507 2.7 1508 - 1509 ==== fred by YOURS after 1510 1.7 1511 2.7 1512 3.7 1513 - 1514 1.7 1515 - 1516 3.7 1517 - 1518 3.7 1519 2.7 1520 1.7 1521 - 1522 ==== fred by MINE after 1523 1.7 1524 - 1525 1.7 1526 - 1527 - 1528 - 1529 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1530 Test 16-ii. Modifying Freds on YOURS 1531 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1532 ==== fred by MINE before 1533 1.7 1534 2.7 1535 3.7 1536 - 1537 1.7 1538 - 1539 3.7 1540 - 1541 3.7 1542 2.7 1543 1.7 1544 - 1545 ==== fred by YOURS before 1546 1.7 1547 2.7 1548 3.7 1549 - 1550 1.7 1551 - 1552 3.7 1553 - 1554 3.7 1555 2.7 1556 1.7 1557 - 1558 ==== fred by MINE after 1559 1.7 1560 2.7 1561 3.7 1562 - 1563 1.7 1564 - 1565 3.7 1566 - 1567 3.7 1568 2.7 1569 1.7 1570 - 1571 ==== fred by YOURS after 1572 2.7 1573 3.7 1574 - 1575 2.7 1576 - 1577 3.7 1578 - 1579 3.7 1580 2.7 1581 - 1582 ==== fred by YOURS after 1583 1.7 1584 - 1585 1.7 1586 - 1587 - 1588 - 1589 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1590 Test 16-iii. Modifying Maries 1591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1592 ==== mary before 1593 1.7 1594 2.7 1595 3.7 1596 - 1597 1.7 1598 - 1599 3.7 1600 - 1601 3.7 1602 2.7 1603 1.7 1604 - 1605 ==== mary after 1606 2.7 1607 3.7 1608 - 1609 2.7 1610 - 1611 3.7 1612 - 1613 3.7 1614 2.7 1615 - 1616 ==== mary after 1617 1.7 1618 - 1619 1.7 1620 - 1621 - 1622 - 1623 1624 ~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~ 1625 1626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1627 Test 17-i. Modifying Freds on MINE 1628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1629 ==== fred by MINE before 1630 1.7 1631 2.7 1632 3.7 1633 - 1634 1.7 1635 - 1636 3.7 1637 - 1638 3.7 1639 2.7 1640 1.7 1641 - 1642 ==== fred by YOURS before 1643 1.7 1644 2.7 1645 3.7 1646 - 1647 1.7 1648 - 1649 3.7 1650 - 1651 3.7 1652 2.7 1653 1.7 1654 - 1655 ==== fred by MINE after 1656 1.7 1657 2.7 1658 - 1659 1.7 1660 - 1661 2.7 1662 - 1663 2.7 1664 1.7 1665 - 1666 ==== fred by YOURS after 1667 1.7 1668 2.7 1669 3.7 1670 - 1671 1.7 1672 - 1673 3.7 1674 - 1675 3.7 1676 2.7 1677 1.7 1678 - 1679 ==== fred by MINE after 1680 3.7 1681 - 1682 3.7 1683 - 1684 - 1685 - 1686 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1687 Test 17-ii. Modifying Freds on YOURS 1688 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1689 ==== fred by MINE before 1690 1.7 1691 2.7 1692 3.7 1693 - 1694 1.7 1695 - 1696 3.7 1697 - 1698 3.7 1699 2.7 1700 1.7 1701 - 1702 ==== fred by YOURS before 1703 1.7 1704 2.7 1705 3.7 1706 - 1707 1.7 1708 - 1709 3.7 1710 - 1711 3.7 1712 2.7 1713 1.7 1714 - 1715 ==== fred by MINE after 1716 1.7 1717 2.7 1718 3.7 1719 - 1720 1.7 1721 - 1722 3.7 1723 - 1724 3.7 1725 2.7 1726 1.7 1727 - 1728 ==== fred by YOURS after 1729 1.7 1730 2.7 1731 - 1732 1.7 1733 - 1734 2.7 1735 - 1736 2.7 1737 1.7 1738 - 1739 ==== fred by YOURS after 1740 3.7 1741 - 1742 3.7 1743 - 1744 - 1745 - 1746 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1747 Test 17-iii. Modifying Maries 1748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1749 ==== mary before 1750 1.7 1751 2.7 1752 3.7 1753 - 1754 1.7 1755 - 1756 3.7 1757 - 1758 3.7 1759 2.7 1760 1.7 1761 - 1762 ==== mary after 1763 1.7 1764 2.7 1765 - 1766 1.7 1767 - 1768 2.7 1769 - 1770 2.7 1771 1.7 1772 - 1773 ==== mary after 1774 3.7 1775 - 1776 3.7 1777 - 1778 - 1779 - 1095 ~~~~~~~~~~~~~~~~~~~ Ease-of-access cases ~~~~~~~~~~~~~~~~~~ 1096 1097 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1098 Test 18-i. Modifying Freds on MINE 1099 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1100 Not implmented 1101 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1102 Test 18-ii. Modifying Freds on YOURS 1103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1104 Not implmented 1105 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1106 Test 18-iii. Modifying Maries 1107 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1108 accessor_cases done 1109 try_pop cases done 1110 origin_mutation cases done -
tests/list/dlist-insert-remove.cfa
r299b8b28 rfc1347d0 19 19 struct fred { 20 20 float adatum; 21 DLISTED_MGD_EXPL_IN(fred, mine)22 DLISTED_MGD_EXPL_IN(fred, yours)21 inline struct mine { inline dlink(fred); }; 22 inline struct yours { inline dlink(fred); }; 23 23 }; 24 25 DLISTED_MGD_EXPL_OUT(fred, mine) 26 DLISTED_MGD_EXPL_OUT(fred, yours) 24 P9_EMBEDDED(fred, fred.mine) 25 P9_EMBEDDED(fred, fred.yours) 26 P9_EMBEDDED(fred.mine, dlink(fred)) 27 P9_EMBEDDED(fred.yours, dlink(fred)) 28 27 29 28 30 void ?{}(fred &this, float adatum) { … … 33 35 struct mary { 34 36 float anotherdatum; 35 DLISTED_MGD_IMPL_IN(mary)37 inline dlink(mary); 36 38 }; 37 39 38 DLISTED_MGD_IMPL_OUT(mary)40 P9_EMBEDDED(mary, dlink(mary)) 39 41 40 42 void ?{}(mary &this, float anotherdatum) { … … 53 55 //////////////////////////////////////////////////////////// 54 56 55 void printMyFredsFwd(fred &f) { 56 while (&f != 0p) { 57 void printMyFredsFwd(fred & f) { 58 with( DLINK_VIA( fred, fred.mine ) ) 59 do { 57 60 sout | f.adatum; 58 &f = &f`in_mine`next;59 }60 } 61 62 void printMyFredsRev(fred &f) { 63 while (&f != 0p){61 } while (f`moveNext); 62 } 63 64 void printMyFredsRev(fred & f) { 65 with( DLINK_VIA( fred, fred.mine ) ) 66 do { 64 67 sout | f.adatum; 65 &f = &f`in_mine`prev;66 }67 } 68 } while (f`movePrev); 69 } 70 68 71 69 72 void printMyFreddies(fred &f1, fred &f2, int isBefore) { … … 73 76 sout | "==== fred by MINE after "; 74 77 } 75 printMyFredsFwd(f1); sout | '-'; 76 printMyFredsRev(f1); sout | '-'; 77 printMyFredsFwd(f2); sout | '-'; 78 printMyFredsRev(f2); sout | '-'; 79 } 80 81 void printYourFredsFwd(fred &f) { 82 while (&f != 0p) { 78 if (&f1) { 79 printMyFredsFwd(f1); sout | '-'; 80 printMyFredsRev(f1); sout | '-'; 81 } else { 82 sout | '-'; sout | '-'; 83 } 84 if (&f2) { 85 printMyFredsFwd(f2); sout | '-'; 86 printMyFredsRev(f2); sout | '-'; 87 } else { 88 sout | '-'; sout | '-'; 89 } 90 } 91 92 void printYourFredsFwd(fred & f) { 93 with( DLINK_VIA( fred, fred.yours ) ) 94 do { 83 95 sout | f.adatum; 84 &f = &f`in_yours`next;85 }86 } 87 88 void printYourFredsRev(fred &f) { 89 while (&f != 0p){96 } while (f`moveNext); 97 } 98 99 void printYourFredsRev(fred & f) { 100 with( DLINK_VIA( fred, fred.yours ) ) 101 do { 90 102 sout | f.adatum; 91 &f = &f`in_yours`prev; 92 } 103 } while (f`movePrev); 93 104 } 94 105 … … 99 110 sout | "==== fred by YOURS after "; 100 111 } 101 printYourFredsFwd(f1); sout | '-'; 102 printYourFredsRev(f1); sout | '-'; 103 printYourFredsFwd(f2); sout | '-'; 104 printYourFredsRev(f2); sout | '-'; 112 if (&f1) { 113 printYourFredsFwd(f1); sout | '-'; 114 printYourFredsRev(f1); sout | '-'; 115 } else { 116 sout | '-'; sout | '-'; 117 } 118 if (&f2) { 119 printYourFredsFwd(f2); sout | '-'; 120 printYourFredsRev(f2); sout | '-'; 121 } else { 122 sout | '-'; sout | '-'; 123 } 105 124 } 106 125 107 126 void printMariesFwd(mary &m) { 108 while (&m != 0p){127 do { 109 128 sout | m.anotherdatum; 110 &m = &m`next; 111 } 129 } while (m`moveNext); 112 130 } 113 131 114 132 void printMariesRev(mary &m) { 115 while (&m != 0p){133 do { 116 134 sout | m.anotherdatum; 117 &m = &m`prev; 118 } 135 } while (m`movePrev); 119 136 } 120 137 … … 125 142 sout | "==== mary after "; 126 143 } 127 printMariesFwd(m1); sout | '-'; 128 printMariesRev(m1); sout | '-'; 129 printMariesFwd(m2); sout | '-'; 130 printMariesRev(m2); sout | '-'; 144 if (&m1) { 145 printMariesFwd(m1); sout | '-'; 146 printMariesRev(m1); sout | '-'; 147 } else { 148 sout | '-'; sout | '-'; 149 } 150 if (&m2) { 151 printMariesFwd(m2); sout | '-'; 152 printMariesRev(m2); sout | '-'; 153 } else { 154 sout | '-'; sout | '-'; 155 } 131 156 } 132 157 … … 153 178 // - from list position #2 moving backward (d) 154 179 // The expected-output comments are in form a;b;c;d where a::=num,num,num 155 180 #if 0 156 181 void test__insertafter_singleton_on_singleton__fred_mine () { 157 182 fred f1 = {3.14}; … … 161 186 printYourFreddies(f1, f2, 1); // 3.14; 3.14; 0.5; 0.5 162 187 163 insert_after(f1`in_mine, f2); 188 diref(fred, fred.mine) f1_mine = f1`from; 189 insert_after(f1_mine, f2); 164 190 165 191 printMyFreddies(f1, f2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) … … 174 200 printYourFreddies(f1, f2, 1); // 3.14; 3.14; 0.5; 0.5 175 201 176 insert_after(f1`in_yours, f2); 202 diref(fred, fred.yours) f1_yours = f1`from; 203 insert_after(f1_yours, f2); 177 204 178 205 printMyFreddies(f1, f2, 0); // 3.14; 3.14; 0.5; 0.5 (unmodified) … … 208 235 printYourFreddies(f1, f2, 1); // 3.14; 3.14; 0.5; 0.5 209 236 210 insert_before(f2`in_mine, f1); 237 diref(fred, fred.mine) f2_mine = f2`from; 238 insert_before(f2_mine, f1); 211 239 212 240 printMyFreddies(f1, f2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) … … 221 249 printYourFreddies(f1, f2, 1); // 3.14; 3.14; 0.5; 0.5 222 250 223 insert_before(f2`in_yours, f1); 251 diref(fred, fred.yours) f2_yours = f2`from; 252 insert_before(f2_yours, f1); 224 253 225 254 printMyFreddies(f1, f2, 0); // 3.14; 3.14; 0.5; 0.5 (unmodified) … … 237 266 printMariatheotokos(m1, m2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 238 267 } 239 268 #endif 240 269 //////////////////////////////////////////////////////////// 241 270 // … … 250 279 // All three tests exercise the case of creating an empty container and 251 280 // adding two items to it. 252 253 281 void test__insertfirst_two_on_empty__fred_mine() { 254 282 … … 256 284 fred f2 = {0.5}; 257 285 258 dlist(fred _in_mine, fred) lf;286 dlist(fred, fred.mine) lf; 259 287 260 288 verify(validate(lf)); … … 277 305 fred f2 = {0.5}; 278 306 279 dlist(fred _in_yours, fred) lf;307 dlist(fred, fred.yours) lf; 280 308 281 309 verify(validate(lf)); … … 292 320 printYourFreddies(f1, f2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 293 321 } 294 295 322 void test__insertfirst_two_on_empty__mary() { 296 323 … … 298 325 mary m2 = {0.5}; 299 326 300 dlist(mary , mary) lm;327 dlist(mary) lm; 301 328 302 329 verify(validate(lm)); … … 325 352 fred f2 = {0.5}; 326 353 327 dlist(fred _in_mine, fred) lf;354 dlist(fred, fred.mine) lf; 328 355 329 356 verify(validate(lf)); … … 346 373 fred f2 = {0.5}; 347 374 348 dlist(fred _in_yours, fred) lf;375 dlist(fred, fred.yours) lf; 349 376 350 377 verify(validate(lf)); … … 367 394 mary m2 = {0.5}; 368 395 369 dlist(mary , mary) lm;396 dlist(mary) lm; 370 397 371 398 verify(validate(lm)); … … 394 421 fred f2 = {0.5}; 395 422 396 dlist(fred _in_mine, fred) lf;397 398 assert( & lf`first == 0p);399 assert( & lf`last == 0p);423 dlist(fred, fred.mine) lf; 424 425 assert( & lf`first == 0p ); 426 assert( & lf`last == 0p ); 400 427 401 428 insert_first(lf, f1); 402 429 403 assert( & lf`first == & f1);404 assert( & lf`last == & f1);430 assert( & lf`first == & f1 ); 431 assert( & lf`last == & f1 ); 405 432 406 433 verify(validate(lf)); 407 434 408 insert_after(f1`in_mine, f2);435 with ( DLINK_VIA(fred, fred.mine) ) insert_after(f1, f2); 409 436 410 437 verify(validate(lf)); … … 413 440 printYourFreddies(f1, f2, 0); // 3.14; 3.14; 0.5; 0.5 (unmodified) 414 441 415 assert( & lf`first == & f1);416 assert( & lf`last == & f2);442 assert( & lf`first == & f1 ); 443 assert( & lf`last == & f2 ); 417 444 } 418 445 … … 422 449 fred f2 = {0.5}; 423 450 424 dlist(fred _in_yours, fred) lf;425 426 assert( & lf`first == 0p);427 assert( & lf`last == 0p);451 dlist(fred, fred.yours) lf; 452 453 assert( & lf`first == 0p ); 454 assert( & lf`last == 0p ); 428 455 429 456 insert_first(lf, f1); 430 457 431 assert( & lf`first == & f1);432 assert( & lf`last == & f1);458 assert( & lf`first == & f1 ); 459 assert( & lf`last == & f1 ); 433 460 434 461 verify(validate(lf)); 435 462 436 insert_after(f1`in_yours, f2);463 with ( DLINK_VIA(fred, fred.yours) ) insert_after(f1, f2); 437 464 438 465 verify(validate(lf)); … … 441 468 printYourFreddies(f1, f2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 442 469 443 assert( & lf`first == & f1);444 assert( & lf`last == & f2);470 assert( & lf`first == & f1 ); 471 assert( & lf`last == & f2 ); 445 472 } 446 473 … … 450 477 mary m2 = {0.5}; 451 478 452 dlist(mary , mary) lm;453 454 assert( & lm`first == 0p);455 assert( & lm`last == 0p);479 dlist(mary) lm; 480 481 assert( & lm`first == 0p ); 482 assert( & lm`last == 0p ); 456 483 457 484 insert_first(lm, m1); 458 485 459 assert( & lm`first == & m1);460 assert( & lm`last == & m1);486 assert( & lm`first == & m1 ); 487 assert( & lm`last == & m1 ); 461 488 462 489 verify(validate(lm)); … … 468 495 printMariatheotokos(m1, m2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 469 496 470 assert( & lm`first == & m1);471 assert( & lm`last == & m2);497 assert( & lm`first == & m1 ); 498 assert( & lm`last == & m2 ); 472 499 } 473 500 … … 487 514 fred f2 = {0.5}; 488 515 489 dlist(fred _in_mine, fred) lf;490 491 assert( & lf`first == 0p);492 assert( & lf`last == 0p);516 dlist(fred, fred.mine) lf; 517 518 assert( & lf`first == 0p ); 519 assert( & lf`last == 0p ); 493 520 494 521 insert_last(lf, f2); 495 522 496 assert( & lf`first == & f2);497 assert( & lf`last == & f2);523 assert( & lf`first == & f2 ); 524 assert( & lf`last == & f2 ); 498 525 499 526 verify(validate(lf)); 500 527 501 insert_before(f2`in_mine, f1);528 with ( DLINK_VIA(fred, fred.mine) ) insert_before(f2, f1); 502 529 503 530 verify(validate(lf)); … … 506 533 printYourFreddies(f1, f2, 0); // 3.14; 3.14; 0.5; 0.5 (unmodified) 507 534 508 assert( & lf`first == & f1);509 assert( & lf`last == & f2);535 assert( & lf`first == & f1 ); 536 assert( & lf`last == & f2 ); 510 537 } 511 538 … … 515 542 fred f2 = {0.5}; 516 543 517 dlist(fred _in_yours, fred) lf;518 519 assert( & lf`first == 0p);520 assert( & lf`last == 0p);544 dlist(fred, fred.yours) lf; 545 546 assert( & lf`first == 0p ); 547 assert( & lf`last == 0p ); 521 548 522 549 insert_last(lf, f2); 523 550 524 assert( & lf`first == & f2);525 assert( & lf`last == & f2);551 assert( & lf`first == & f2 ); 552 assert( & lf`last == & f2 ); 526 553 527 554 verify(validate(lf)); 528 555 529 insert_before(f2`in_yours, f1);556 with ( DLINK_VIA(fred, fred.yours) )insert_before(f2, f1); 530 557 531 558 verify(validate(lf)); … … 534 561 printYourFreddies(f1, f2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 535 562 536 assert( & lf`first == & f1);537 assert( & lf`last == & f2);563 assert( & lf`first == & f1 ); 564 assert( & lf`last == & f2 ); 538 565 } 539 566 … … 543 570 mary m2 = {0.5}; 544 571 545 dlist(mary , mary) lm;546 547 assert( & lm`first == 0p);548 assert( & lm`last == 0p);572 dlist(mary) lm; 573 574 assert( & lm`first == 0p ); 575 assert( & lm`last == 0p ); 549 576 550 577 insert_last(lm, m2); 551 578 552 assert( & lm`first == & m2);553 assert( & lm`last == & m2);579 assert( & lm`first == & m2 ); 580 assert( & lm`last == & m2 ); 554 581 555 582 verify(validate(lm)); … … 561 588 printMariatheotokos(m1, m2, 0); // 3.14, 0.5; 3.14; 0.5; 0.5, 3.14 (modified) 562 589 563 assert(& lm`first == & m1); 564 assert(& lm`last == & m2); 565 } 590 assert( & lm`first == & m1 ); 591 assert( & lm`last == & m2 ); 592 } 593 #if 0 566 594 567 595 //////////////////////////////////////////////////////////// … … 846 874 // 847 875 //////////////////////////////////////////////////////////// 848 876 #endif 849 877 void test__remove_at_head__fred_mine() { 850 878 … … 853 881 fred f3 = {3.7}; 854 882 855 dlist(fred _in_mine, fred) flm;883 dlist(fred, fred.mine) flm; 856 884 insert_last(flm, f1); 857 885 insert_last(flm, f2); 858 886 insert_last(flm, f3); 859 887 860 dlist(fred _in_yours, fred) fly;888 dlist(fred, fred.yours) fly; 861 889 insert_last(fly, f1); 862 890 insert_last(fly, f2); … … 869 897 verify(validate(flm)); 870 898 871 remove(f1`in_mine);899 with( DLINK_VIA(fred, fred.mine) ) remove(f1); 872 900 873 901 verify(validate(fly)); … … 881 909 882 910 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 883 assert(f1.$links_mine.next.is_terminator == false); 884 assert(f1.$links_mine.prev.is_terminator == false); 885 } 911 // assert(f1.$links_mine.next.is_terminator == false); 912 // assert(f1.$links_mine.prev.is_terminator == false); 913 } 914 886 915 887 916 void test__remove_at_head__fred_yours() { … … 891 920 fred f3 = {3.7}; 892 921 893 dlist(fred _in_mine, fred) flm;922 dlist(fred, fred.mine) flm; 894 923 insert_last(flm, f1); 895 924 insert_last(flm, f2); 896 925 insert_last(flm, f3); 897 926 898 dlist(fred _in_yours, fred) fly;927 dlist(fred, fred.yours) fly; 899 928 insert_last(fly, f1); 900 929 insert_last(fly, f2); … … 907 936 verify(validate(flm)); 908 937 909 remove(f1`in_yours);938 with( DLINK_VIA(fred, fred.yours) ) remove(f1); 910 939 911 940 verify(validate(fly)); … … 919 948 920 949 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 921 assert(f1.$links_yours.next.is_terminator == false);922 assert(f1.$links_yours.prev.is_terminator == false);950 // assert(f1.$links_yours.next.is_terminator == false); 951 // assert(f1.$links_yours.prev.is_terminator == false); 923 952 } 924 953 … … 929 958 mary m3 = {3.7}; 930 959 931 dlist(mary , mary) ml;960 dlist(mary) ml; 932 961 insert_last(ml, m1); 933 962 insert_last(ml, m2); … … 948 977 949 978 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 950 assert(m1.$links.next.is_terminator == false);951 assert(m1.$links.prev.is_terminator == false);979 // assert(m1.$links.next.is_terminator == false); 980 // assert(m1.$links.prev.is_terminator == false); 952 981 } 953 982 … … 968 997 fred f3 = {3.7}; 969 998 970 dlist(fred _in_mine, fred) flm;999 dlist(fred, fred.mine) flm; 971 1000 insert_last(flm, f1); 972 1001 insert_last(flm, f2); 973 1002 insert_last(flm, f3); 974 1003 975 dlist(fred _in_yours, fred) fly;1004 dlist(fred, fred.yours) fly; 976 1005 insert_last(fly, f1); 977 1006 insert_last(fly, f2); … … 984 1013 verify(validate(flm)); 985 1014 986 remove(f3`in_mine);1015 with( DLINK_VIA(fred, fred.mine) ) remove(f3); 987 1016 988 1017 verify(validate(fly)); … … 996 1025 997 1026 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 998 assert(f3.$links_mine.next.is_terminator == false);999 assert(f3.$links_mine.prev.is_terminator == false);1027 // assert(f3.$links_mine.next.is_terminator == false); 1028 // assert(f3.$links_mine.prev.is_terminator == false); 1000 1029 } 1001 1030 … … 1006 1035 fred f3 = {3.7}; 1007 1036 1008 dlist(fred _in_mine, fred) flm;1037 dlist(fred, fred.mine) flm; 1009 1038 insert_last(flm, f1); 1010 1039 insert_last(flm, f2); 1011 1040 insert_last(flm, f3); 1012 1041 1013 dlist(fred _in_yours, fred) fly;1042 dlist(fred, fred.yours) fly; 1014 1043 insert_last(fly, f1); 1015 1044 insert_last(fly, f2); … … 1022 1051 verify(validate(flm)); 1023 1052 1024 remove(f3`in_yours);1053 with( DLINK_VIA(fred, fred.yours) ) remove(f3); 1025 1054 1026 1055 verify(validate(fly)); … … 1034 1063 1035 1064 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 1036 assert(f3.$links_yours.next.is_terminator == false);1037 assert(f3.$links_yours.prev.is_terminator == false);1065 // assert(f3.$links_yours.next.is_terminator == false); 1066 // assert(f3.$links_yours.prev.is_terminator == false); 1038 1067 } 1039 1068 … … 1044 1073 mary m3 = {3.7}; 1045 1074 1046 dlist(mary , mary) ml;1075 dlist(mary) ml; 1047 1076 insert_last(ml, m1); 1048 1077 insert_last(ml, m2); … … 1063 1092 1064 1093 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 1065 assert(m3.$links.next.is_terminator == false);1066 assert(m3.$links.prev.is_terminator == false);1094 // assert(m3.$links.next.is_terminator == false); 1095 // assert(m3.$links.prev.is_terminator == false); 1067 1096 } 1068 1097 … … 1081 1110 fred f = {0.7}; 1082 1111 1083 dlist(fred _in_mine, fred) flm;1112 dlist(fred, fred.mine) flm; 1084 1113 insert_last(flm, f); 1085 1114 1086 dlist(fred _in_yours, fred) fly;1115 dlist(fred, fred.yours) fly; 1087 1116 insert_last(fly, f); 1088 1117 … … 1093 1122 verify(validate(flm)); 1094 1123 1095 remove(f`in_mine);1096 1097 verify(validate(fly)); 1098 verify(validate(flm)); 1099 1100 assert( & flm`first == 0p);1101 assert( & flm`last == 0p);1124 with( DLINK_VIA(fred, fred.mine) ) remove(f); 1125 1126 verify(validate(fly)); 1127 verify(validate(flm)); 1128 1129 assert( & flm`first == 0p ); 1130 assert( & flm`last == 0p ); 1102 1131 1103 1132 printYourFreddies(fly`first, fly`last, 0); // 0.7; 0.7; 0.7; 0.7 (unmodified) … … 1107 1136 1108 1137 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 1109 assert(f.$links_mine.next.is_terminator == false);1110 assert(f.$links_mine.prev.is_terminator == false);1138 // assert(f.$links_mine.next.is_terminator == false); 1139 // assert(f.$links_mine.prev.is_terminator == false); 1111 1140 1112 1141 insert_last(flm, f); … … 1120 1149 fred f = {0.7}; 1121 1150 1122 dlist(fred _in_mine, fred) flm;1151 dlist(fred, fred.mine) flm; 1123 1152 insert_last(flm, f); 1124 1153 1125 dlist(fred _in_yours, fred) fly;1154 dlist(fred, fred.yours) fly; 1126 1155 insert_last(fly, f); 1127 1156 … … 1132 1161 verify(validate(flm)); 1133 1162 1134 remove(f`in_yours);1135 1136 verify(validate(fly)); 1137 verify(validate(flm)); 1138 1139 assert( & fly`first == 0p);1140 assert( & fly`last == 0p);1163 with( DLINK_VIA(fred, fred.yours) ) remove(f); 1164 1165 verify(validate(fly)); 1166 verify(validate(flm)); 1167 1168 assert( & fly`first == 0p ); 1169 assert( & fly`last == 0p ); 1141 1170 1142 1171 printYourFreddies(flm`first, flm`last, 0); // 0.7; 0.7; 0.7; 0.7 (unmodified) … … 1146 1175 1147 1176 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 1148 assert(f.$links_yours.next.is_terminator == false);1149 assert(f.$links_yours.prev.is_terminator == false);1177 // assert(f.$links_yours.next.is_terminator == false); 1178 // assert(f.$links_yours.prev.is_terminator == false); 1150 1179 1151 1180 insert_last(fly, f); … … 1159 1188 mary m = {0.7}; 1160 1189 1161 dlist(mary , mary) ml;1190 dlist(mary) ml; 1162 1191 insert_last(ml, m); 1163 1192 … … 1170 1199 verify(validate(ml)); 1171 1200 1172 assert( & ml`first == 0p);1173 assert( & ml`last == 0p);1201 assert( & ml`first == 0p ); 1202 assert( & ml`last == 0p ); 1174 1203 1175 1204 // observe f is solo in mine (now unlisted); in yours, it was just traversed … … 1177 1206 1178 1207 // TODO: decide on appropriate ovservable outcome (is_listed?) and its itended semantics 1179 assert(m.$links.next.is_terminator == false);1180 assert(m.$links.prev.is_terminator == false);1208 // assert(m.$links.next.is_terminator == false); 1209 // assert(m.$links.prev.is_terminator == false); 1181 1210 1182 1211 insert_last(ml, m); … … 1203 1232 fred f3 = {3.7}; 1204 1233 1205 dlist(fred _in_mine, fred) flm;1234 dlist(fred, fred.mine) flm; 1206 1235 insert_last(flm, f1); 1207 1236 insert_last(flm, f2); 1208 1237 insert_last(flm, f3); 1209 1238 1210 dlist(fred _in_yours, fred) fly;1239 dlist(fred, fred.yours) fly; 1211 1240 insert_last(fly, f1); 1212 1241 insert_last(fly, f2); … … 1219 1248 verify(validate(flm)); 1220 1249 1221 fred & popped = pop_first(flm);1250 fred & popped = try_pop_front(flm); 1222 1251 1223 1252 verify(validate(fly)); … … 1239 1268 fred f3 = {3.7}; 1240 1269 1241 dlist(fred _in_mine, fred) flm;1270 dlist(fred, fred.mine) flm; 1242 1271 insert_last(flm, f1); 1243 1272 insert_last(flm, f2); 1244 1273 insert_last(flm, f3); 1245 1274 1246 dlist(fred _in_yours, fred) fly;1275 dlist(fred, fred.yours) fly; 1247 1276 insert_last(fly, f1); 1248 1277 insert_last(fly, f2); … … 1255 1284 verify(validate(flm)); 1256 1285 1257 fred & popped = pop_first(fly);1286 fred & popped = try_pop_front(fly); 1258 1287 1259 1288 verify(validate(fly)); … … 1275 1304 mary m3 = {3.7}; 1276 1305 1277 dlist(mary , mary) ml;1306 dlist(mary) ml; 1278 1307 insert_last(ml, m1); 1279 1308 insert_last(ml, m2); … … 1284 1313 verify(validate(ml)); 1285 1314 1286 mary & popped = pop_first(ml);1315 mary & popped = try_pop_front(ml); 1287 1316 1288 1317 verify(validate(ml)); … … 1302 1331 fred f3 = {3.7}; 1303 1332 1304 dlist(fred _in_mine, fred) flm;1333 dlist(fred, fred.mine) flm; 1305 1334 insert_last(flm, f1); 1306 1335 insert_last(flm, f2); 1307 1336 insert_last(flm, f3); 1308 1337 1309 dlist(fred _in_yours, fred) fly;1338 dlist(fred, fred.yours) fly; 1310 1339 insert_last(fly, f1); 1311 1340 insert_last(fly, f2); … … 1318 1347 verify(validate(flm)); 1319 1348 1320 fred & popped = pop_last(flm);1349 fred & popped = try_pop_back(flm); 1321 1350 1322 1351 verify(validate(fly)); … … 1338 1367 fred f3 = {3.7}; 1339 1368 1340 dlist(fred _in_mine, fred) flm;1369 dlist(fred, fred.mine) flm; 1341 1370 insert_last(flm, f1); 1342 1371 insert_last(flm, f2); 1343 1372 insert_last(flm, f3); 1344 1373 1345 dlist(fred _in_yours, fred) fly;1374 dlist(fred, fred.yours) fly; 1346 1375 insert_last(fly, f1); 1347 1376 insert_last(fly, f2); … … 1354 1383 verify(validate(flm)); 1355 1384 1356 fred & popped = pop_last(fly);1385 fred & popped = try_pop_back(fly); 1357 1386 1358 1387 verify(validate(fly)); … … 1374 1403 mary m3 = {3.7}; 1375 1404 1376 dlist(mary , mary) ml;1405 dlist(mary) ml; 1377 1406 insert_last(ml, m1); 1378 1407 insert_last(ml, m2); … … 1383 1412 verify(validate(ml)); 1384 1413 1385 mary & popped = pop_last(ml);1414 mary & popped = try_pop_back(ml); 1386 1415 1387 1416 verify(validate(ml)); … … 1397 1426 //////////////////////////////////////////////////////////// 1398 1427 // 1428 // Section 4g 1429 // 1430 // Test cases of `isEmpty, `hasPrev, `hasNext, 1431 // try_pop_front, try_pop_back, modifications via `elems 1432 // 1433 // Example of call-side user code 1434 // 1435 //////////////////////////////////////////////////////////// 1436 1437 void test__accessor_cases__mary() { 1438 1439 mary m1 = {1.7}; 1440 mary m2 = {2.7}; 1441 mary m3 = {3.7}; 1442 1443 dlist(mary) ml; assert( ml`isEmpty); 1444 1445 insert_last(ml, m1); assert(!ml`isEmpty); 1446 insert_last(ml, m2); assert(!ml`isEmpty); 1447 insert_last(ml, m3); assert(!ml`isEmpty); 1448 1449 mary & m1prev = m1`prev; 1450 mary & m1next = m1`next; 1451 mary & m2prev = m2`prev; 1452 mary & m2next = m2`next; 1453 mary & m3prev = m3`prev; 1454 mary & m3next = m3`next; 1455 1456 assert (&m1prev == 0p); 1457 assert (&m1next == &m2); 1458 assert (&m2prev == &m1); 1459 assert (&m2next == &m3); 1460 assert (&m3prev == &m2); 1461 assert (&m3next == 0p); 1462 1463 assert(!m1`hasPrev); 1464 assert( m1`hasNext); 1465 assert( m2`hasPrev); 1466 assert( m2`hasNext); 1467 assert( m3`hasPrev); 1468 assert(!m3`hasNext); 1469 1470 printf("accessor_cases done\n"); 1471 } 1472 1473 void test__try_pop__mary() { 1474 1475 mary m1 = {1.7}; 1476 mary m2 = {2.7}; 1477 mary m3 = {3.7}; 1478 1479 dlist(mary) ml; 1480 1481 mary &m1r = *0p; 1482 mary &m2r = *0p; 1483 mary &m3r = *0p; 1484 mary &mxr = *0p; 1485 1486 // queue, back to front 1487 1488 assert( ml`isEmpty); 1489 1490 insert_last(ml, m1); 1491 insert_last(ml, m2); 1492 insert_last(ml, m3); 1493 1494 &m1r = & try_pop_front(ml); assert(!ml`isEmpty); 1495 &m2r = & try_pop_front(ml); assert(!ml`isEmpty); 1496 &m3r = & try_pop_front(ml); assert( ml`isEmpty); 1497 &mxr = & try_pop_front(ml); assert( ml`isEmpty); 1498 1499 assert( &m1r == &m1 ); 1500 assert( &m2r == &m2 ); 1501 assert( &m3r == &m3 ); 1502 assert( &mxr == 0p ); 1503 1504 &m1r = 0p; 1505 &m2r = 0p; 1506 &m3r = 0p; 1507 1508 // queue, front to back 1509 1510 assert( ml`isEmpty); 1511 1512 insert_first(ml, m1); 1513 insert_first(ml, m2); 1514 insert_first(ml, m3); 1515 1516 &m1r = & try_pop_back(ml); assert(!ml`isEmpty); 1517 &m2r = & try_pop_back(ml); assert(!ml`isEmpty); 1518 &m3r = & try_pop_back(ml); assert( ml`isEmpty); 1519 &mxr = & try_pop_back(ml); assert( ml`isEmpty); 1520 1521 assert( &m1r == &m1 ); 1522 assert( &m2r == &m2 ); 1523 assert( &m3r == &m3 ); 1524 assert( &mxr == 0p ); 1525 1526 &m1r = 0p; 1527 &m2r = 0p; 1528 &m3r = 0p; 1529 1530 // stack at front 1531 1532 assert( ml`isEmpty); 1533 1534 insert_first(ml, m1); 1535 insert_first(ml, m2); 1536 insert_first(ml, m3); 1537 1538 &m3r = & try_pop_front(ml); assert(!ml`isEmpty); 1539 &m2r = & try_pop_front(ml); assert(!ml`isEmpty); 1540 &m1r = & try_pop_front(ml); assert( ml`isEmpty); 1541 &mxr = & try_pop_front(ml); assert( ml`isEmpty); 1542 1543 assert( &m1r == &m1 ); 1544 assert( &m2r == &m2 ); 1545 assert( &m3r == &m3 ); 1546 assert( &mxr == 0p ); 1547 1548 &m1r = 0p; 1549 &m2r = 0p; 1550 &m3r = 0p; 1551 1552 // stack at back 1553 1554 assert( ml`isEmpty); 1555 1556 insert_last(ml, m1); 1557 insert_last(ml, m2); 1558 insert_last(ml, m3); 1559 1560 &m3r = & try_pop_back(ml); assert(!ml`isEmpty); 1561 &m2r = & try_pop_back(ml); assert(!ml`isEmpty); 1562 &m1r = & try_pop_back(ml); assert( ml`isEmpty); 1563 &mxr = & try_pop_back(ml); assert( ml`isEmpty); 1564 1565 assert( &m1r == &m1 ); 1566 assert( &m2r == &m2 ); 1567 assert( &m3r == &m3 ); 1568 assert( &mxr == 0p ); 1569 1570 &m1r = 0p; 1571 &m2r = 0p; 1572 &m3r = 0p; 1573 1574 printf("try_pop cases done\n"); 1575 } 1576 1577 void test__origin_mutation__mary() { 1578 1579 mary m1 = {1.7}; 1580 1581 dlist(mary) ml; 1582 mary & mlorigin = ml`elems; 1583 1584 // insert before the origin 1585 1586 insert_before( ml`elems, m1 ); 1587 assert( ! ml`isEmpty ); 1588 1589 mary & mlfirst = ml`first; 1590 mary & mllast = ml`last; 1591 1592 assert( &m1 == & mlfirst ); 1593 assert( &m1 == & mllast ); 1594 1595 // moveNext after last goes back to origin, &vv 1596 1597 bool canMoveNext = mllast`moveNext; 1598 bool canMovePrev = mlfirst`movePrev; 1599 1600 assert( ! canMoveNext ); 1601 assert( ! canMovePrev ); 1602 1603 assert( &mlorigin == & mlfirst ); 1604 assert( &mlorigin == & mllast ); 1605 1606 printf("origin_mutation cases done\n"); 1607 } 1608 1609 //////////////////////////////////////////////////////////// 1610 // 1399 1611 // Section 5 1400 1612 // … … 1404 1616 1405 1617 int main() { 1406 1618 #if 0 1407 1619 sout | "~~~~~~~~~~~~~~~~~ Headless List Tests - insert_after ~~~~~~~~~~~~~~~~"; 1408 1620 sout | ""; … … 1441 1653 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1442 1654 test__insertbefore_singleton_on_singleton__mary(); 1443 1655 #endif 1444 1656 sout | ""; 1445 1657 sout | "~~~~~~~~~~~~~~~~~ Headed List Tests - insert_first ~~~~~~~~~~~~~~~~~~"; … … 1517 1729 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1518 1730 test__insertbefore_before_first__mary(); 1731 #if 0 1519 1732 1520 1733 sout | ""; … … 1574 1787 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1575 1788 test__remove_at_last__mary(); 1576 1789 #endif 1577 1790 sout | ""; 1578 1791 sout | "~~~~~~~~~~ Element removal tests on Headed List: at first ~~~~~~~~~~"; … … 1670 1883 test__pop_last__maries(); 1671 1884 1885 sout | ""; 1886 sout | "~~~~~~~~~~~~~~~~~~~ Ease-of-access cases ~~~~~~~~~~~~~~~~~~"; 1887 sout | ""; 1888 1889 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1890 sout | "Test 18-i. Modifying Freds on MINE"; 1891 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1892 sout | "Not implmented"; 1893 1894 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1895 sout | "Test 18-ii. Modifying Freds on YOURS"; 1896 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1897 sout | "Not implmented"; 1898 1899 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1900 sout | "Test 18-iii. Modifying Maries"; 1901 sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; 1902 1903 test__accessor_cases__mary(); 1904 test__try_pop__mary(); 1905 test__origin_mutation__mary(); 1906 1672 1907 return 0; 1673 1908 }
Note:
See TracChangeset
for help on using the changeset viewer.