Changes in / [3ce0c915:11b7028]


Ignore:
Files:
1 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • configure

    r3ce0c915 r11b7028  
    678678CFA_INCDIR
    679679CFA_PREFIX
    680 DOendif
    681 DOifskipcompile
    682680BUILD_CONCURRENCY_FALSE
    683681BUILD_CONCURRENCY_TRUE
     
    33443342
    33453343
    3346 DOifskipcompile='ifeq ($(skipcompile),yes)
    3347 else'
    3348 
    3349 
    3350 
    3351 DOendif='endif'
    3352 
    3353 
    3354 
    33553344if test "x$prefix" = "xNONE"; then
    33563345        cfa_prefix=${ac_default_prefix}
  • configure.ac

    r3ce0c915 r11b7028  
    130130AM_CONDITIONAL([BUILD_NO_LIB], [test "x$build_release$build_debug" = "xnono"])
    131131AM_CONDITIONAL([BUILD_CONCURRENCY], [test "x$build_threading" = "xyes"])
    132 
    133 DOifskipcompile='ifeq ($(skipcompile),yes)
    134 else'
    135 AC_SUBST([DOifskipcompile])
    136 AM_SUBST_NOTMAKE([DOifskipcompile])
    137 
    138 DOendif='endif'
    139 AC_SUBST([DOendif])
    140 AM_SUBST_NOTMAKE([DOendif])
    141132
    142133if test "x$prefix" = "xNONE"; then
  • doc/papers/general/Paper.tex

    r3ce0c915 r11b7028  
    148148The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects.
    149149This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    150 The TIOBE\cite{TIOBE} ranks the top 5 most popular programming languages as: Java 16\%, \Textbf{C 7\%}, \Textbf{\CC 5\%}, \Csharp 4\%, Python 4\% = 36\%, where the next 50 languages are less than 3\% each with a long tail.
     150The \cite{TIOBE} ranks the top 5 most popular programming languages as: Java 16\%, \Textbf{C 7\%}, \Textbf{\CC 5\%}, \Csharp 4\%, Python 4\% = 36\%, where the next 50 languages are less than 3\% each with a long tail.
    151151The top 3 rankings over the past 30 years are:
    152152\lstDeleteShortInline@%
     
    185185\label{sec:poly-fns}
    186186
    187 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfield\cite{Ditchfield92}, and first implemented by Bilson\cite{Bilson03}.
     187\CFA{}\hspace{1pt}'s polymorphism was originally formalized by \cite{Ditchfield92}, and first implemented by \cite{Bilson03}.
    188188The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a @forall@ clause (giving the language its name):
    189189\begin{lstlisting}
     
    258258}
    259259\end{lstlisting}
    260 Within the block, the nested version of @?<?@ performs @?>?@ and this local version overrides the built-in @?<?@ so it is passed to @qsort@.
     260Within the block, the nested version of @<@ performs @>@ and this local version overrides the built-in @<@ so it is passed to @qsort@.
    261261Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types.
    262262
     
    337337% While a nominal-inheritance system with associated types could model one of those two relationships by making @El@ an associated type of @Ptr@ in the @pointer_like@ implementation, few such systems could model both relationships simultaneously.
    338338
     339
    339340\section{Generic Types}
    340341
     
    465466However, the \CFA type-checker ensures matching types are used by all calls to @?+?@, preventing nonsensical computations like adding a length to a volume.
    466467
     468
    467469\section{Tuples}
    468470\label{sec:tuples}
     
    542544p`->0` = 5;                                                                     $\C{// change quotient}$
    543545bar( qr`.1`, qr );                                                      $\C{// pass remainder and quotient/remainder}$
    544 rem = [div( 13, 5 ), 42]`.0.1`;                         $\C{// access 2nd component of 1st component of tuple expression}$
     546rem = [42, div( 13, 5 )]`.0.1`;                         $\C{// access 2nd component of 1st component of tuple expression}$
    545547\end{lstlisting}
    546548
     
    728730\end{lstlisting}
    729731Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution.
    730 This relaxation is possible by extending the thunk scheme described by Bilson\cite{Bilson03}.
     732This relaxation is possible by extending the thunk scheme described by~\cite{Bilson03}.
    731733Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function:
    732734\begin{lstlisting}
     
    899901\end{comment}
    900902
    901 \section{Improved Procedural Paradigm}
    902 
    903 It is important to the design team that \CFA subjectively ``feel like'' C to user programmers.
    904 An important part of this subjective feel is maintaining C's procedural programming paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust.
    905 Maintaining this procedural paradigm means that coding patterns that work in C will remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development.
    906 Nonetheless, some features of object-oriented languages are undeniably convienient, and the \CFA design team has attempted to adapt them to a procedural paradigm so as to incorporate their benefits into \CFA; two of these features are resource management and name scoping.
    907 
    908 \subsection{Constructors and Destructors}
    909 
    910 One of the strengths of C is the control over memory management it gives programmers, allowing resource release to be more consistent and precisely timed than is possible with garbage-collected memory management.
    911 However, this manual approach to memory management is often verbose, and it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory.
    912 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Allocation Is Initialization (RAII), implemented by means of special \emph{constructor} and \emph{destructor} functions; we have implemented a similar feature in \CFA.
    913 
    914 \TODO{Fill out section. Mention field-constructors and at-equal escape hatch to C-style initialization. Probably pull some text from Rob's thesis for first draft.}
    915 
    916 \subsection{with Statement}
    917 
    918 In any programming language, some functions have a naturally close relationship with a particular data type.
    919 Object-oriented programming allows this close relationship to be codified in the language by making such functions \emph{class methods} of their related data type.
    920 Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type.
    921 When writing C functions in an object-oriented style, this un-prefixed access is swiftly missed, as access to fields of a @Foo* f@ requires an extra three characters @f->@ every time, which disrupts coding flow and clutters the produced code.
    922 
    923 \TODO{Fill out section. Be sure to mention arbitrary expressions in with-blocks, recent change driven by Thierry to prioritize field name over parameters.}
    924 
    925 \section{References}
    926 
    927 \TODO{Pull draft text from user manual; make sure to discuss nested references and rebind operator drawn from lvalue-addressof operator}
    928903
    929904\section{Evaluation}
     
    10381013In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate-compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.
    10391014The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed properties for a type.
    1040 Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
     1015Until \CC~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
    10411016furthermore, \CC concepts are restricted to template polymorphism.
    10421017
     
    10461021In \CFA terms, all Cyclone polymorphism must be dtype-static.
    10471022While the Cyclone design provides the efficiency benefits discussed in Section~\ref{sec:generic-apps} for dtype-static polymorphism, it is more restrictive than \CFA's general model.
    1048 Smith and Volpano~\cite{Smith98} present Polymorphic C, an ML dialect with polymorphic functions, C-like syntax, and pointer types; it lacks many of C's features, however, most notably structure types, and so is not a practical C replacement.
    1049 
    1050 Objective-C~\cite{obj-c-book} is an industrially successful extension to C.
     1023\cite{Smith98} present Polymorphic C, an ML dialect with polymorphic functions and C-like syntax and pointer types; it lacks many of C's features, however, most notably structure types, and so is not a practical C replacement.
     1024
     1025\cite{obj-c-book} is an industrially successful extension to C.
    10511026However, Objective-C is a radical departure from C, using an object-oriented model with message-passing.
    10521027Objective-C did not support type-checked generics until recently \cite{xcode7}, historically using less-efficient runtime checking of object types.
    1053 The GObject~\cite{GObject} framework also adds object-oriented programming with runtime type-checking and reference-counting garbage-collection to C;
     1028The~\cite{GObject} framework also adds object-oriented programming with runtime type-checking and reference-counting garbage-collection to C;
    10541029these features are more intrusive additions than those provided by \CFA, in addition to the runtime overhead of reference-counting.
    1055 Vala~\cite{Vala} compiles to GObject-based C, adding the burden of learning a separate language syntax to the aforementioned demerits of GObject as a modernization path for existing C code-bases.
     1030\cite{Vala} compiles to GObject-based C, adding the burden of learning a separate language syntax to the aforementioned demerits of GObject as a modernization path for existing C code-bases.
    10561031Java~\cite{Java8} included generic types in Java~5, which are type-checked at compilation and type-erased at runtime, similar to \CFA's.
    10571032However, in Java, each object carries its own table of method pointers, while \CFA passes the method pointers separately to maintain a C-compatible layout.
    10581033Java is also a garbage-collected, object-oriented language, with the associated resource usage and C-interoperability burdens.
    10591034
    1060 D~\cite{D}, Go, and Rust~\cite{Rust} are modern, compiled languages with abstraction features similar to \CFA traits, \emph{interfaces} in D and Go and \emph{traits} in Rust.
     1035D~\cite{D}, Go, and~\cite{Rust} are modern, compiled languages with abstraction features similar to \CFA traits, \emph{interfaces} in D and Go and \emph{traits} in Rust.
    10611036However, each language represents a significant departure from C in terms of language model, and none has the same level of compatibility with C as \CFA.
    10621037D and Go are garbage-collected languages, imposing the associated runtime overhead.
     
    10791054\CCeleven introduced @std::tuple@ as a library variadic template structure.
    10801055Tuples are a generalization of @std::pair@, in that they allow for arbitrary length, fixed-size aggregation of heterogeneous values.
    1081 Operations include @std::get<N>@ to extract values, @std::tie@ to create a tuple of references used for assignment, and lexicographic comparisons.
     1056Operations include @std::get<N>@ to extract vales, @std::tie@ to create a tuple of references used for assignment, and lexicographic comparisons.
    10821057\CCseventeen proposes \emph{structured bindings}~\cite{Sutter15} to eliminate pre-declaring variables and use of @std::tie@ for binding the results.
    10831058This extension requires the use of @auto@ to infer the types of the new variables, so complicated expressions with a non-obvious type must be documented with some other mechanism.
     
    10931068The goal of \CFA is to provide an evolutionary pathway for large C development-environments to be more productive and safer, while respecting the talent and skill of C programmers.
    10941069While other programming languages purport to be a better C, they are in fact new and interesting languages in their own right, but not C extensions.
    1095 The purpose of this paper is to introduce \CFA, and showcase language features that illustrate the \CFA type-system and approaches taken to achieve the goal of evolutionary C extension.
     1070The purpose of this paper is to introduce \CFA, and showcase two language features that illustrate the \CFA type-system and approaches taken to achieve the goal of evolutionary C extension.
    10961071The contributions are a powerful type-system using parametric polymorphism and overloading, generic types, and tuples, which all have complex interactions.
    10971072The work is a challenging design, engineering, and implementation exercise.
  • doc/theses/thierry_delisle/Makefile

    r3ce0c915 r11b7028  
    9898        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
    9999
    100 #-----------------------------------------------------------------------------------
    101 # Tools to generate png files
    102 # to create a png we create a pdf and convert it to png
    103 %.png : build/%.pstex figures/%.tex
    104         echo ${basename $@}
    105         ${LaTeX} figures/${basename $@}.tex
    106         dvips build/${basename $@}.dvi -o build/${basename $@}.ps
    107         ps2pdf build/${basename $@}.ps
    108         convert -negate ${basename $@}.pdf $@
    109 
    110 # creating a pdf of a figure requires generating some latex that just includes the figure
    111 figures/%.tex: build/%.pstex
     100%.tex: %.pstex
    112101        echo -n         "\documentclass[preview]{standalone}\n"         \
    113102                        "\usepackage[T1]{fontenc}\n"                    \
     
    121110                        "\end{document}" > $@
    122111
     112%.png : %.pstex %.tex
     113        echo ${basename $@}
     114        ${LaTeX} figures/${basename $@}.tex
     115        dvips build/${basename $@}.dvi -o build/${basename $@}.ps
     116        ps2pdf build/${basename $@}.ps
     117        convert -negate ${basename $@}.pdf $@
     118
    123119# Local Variables: #
    124120# compile-command: "make" #
  • src/benchmark/Makefile.am

    r3ce0c915 r11b7028  
    2323STATS    = ${TOOLSDIR}stat.py
    2424repeats  = 30
    25 skipcompile = no
    2625TIME_FORMAT = "%E"
    2726PRINT_FORMAT = %20s: #Comments needed for spacing
     
    4443%.runquiet :
    4544        @+make $(basename $@)
    46         @taskset -c 1 ./a.out
     45        @./a.out
    4746        @rm -f a.out
    4847
     
    6059        @echo -e '\t"githash": "'${githash}'",'
    6160        @echo -e '\t"arch": "'   ${arch}   '",'
    62 @DOifskipcompile@
    6361        @echo -e '\t"compile": {'
    6462        @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :'
    6563        @echo -e '\t\t"dummy" : {}'
    6664        @echo -e '\t},'
    67 @DOendif@
    6865        @echo -e '\t"ctxswitch": {'
    6966        @echo -en '\t\t"coroutine":'
  • src/benchmark/Makefile.in

    r3ce0c915 r11b7028  
    253253STATS = ${TOOLSDIR}stat.py
    254254repeats = 30
    255 skipcompile = no
    256255TIME_FORMAT = "%E"
    257256PRINT_FORMAT = %20s: #Comments needed for spacing
     
    460459%.runquiet :
    461460        @+make $(basename $@)
    462         @taskset -c 1 ./a.out
     461        @./a.out
    463462        @rm -f a.out
    464463
     
    474473        @echo -e '\t"githash": "'${githash}'",'
    475474        @echo -e '\t"arch": "'   ${arch}   '",'
    476 @DOifskipcompile@
    477475        @echo -e '\t"compile": {'
    478476        @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :'
    479477        @echo -e '\t\t"dummy" : {}'
    480478        @echo -e '\t},'
    481 @DOendif@
    482479        @echo -e '\t"ctxswitch": {'
    483480        @echo -en '\t\t"coroutine":'
  • src/driver/cfa.cc

    r3ce0c915 r11b7028  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  1 22:26:10 2018
    13 // Update Count     : 163
     12// Last Modified On : Tue Jan 30 15:46:15 2018
     13// Update Count     : 161
    1414//
    1515
     
    358358                args[nargs] = "-D__int8_t_defined";                             // prevent gcc type-size attributes
    359359                nargs += 1;
     360                args[nargs] = "-D__NO_STRING_INLINES";                  // prevent gcc strcmp unrolling
     361                nargs += 1;
    360362                args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
    361363                nargs += 1;
  • src/libcfa/concurrency/kernel.c

    r3ce0c915 r11b7028  
    5959
    6060volatile thread_local bool preemption_in_progress = 0;
    61 volatile thread_local bool preemption_enabled = false;
    6261volatile thread_local unsigned short disable_preempt_count = 1;
    6362
     
    197196                        if(readyThread)
    198197                        {
    199                                 verify( !preemption_enabled );
     198                                verify( disable_preempt_count > 0 );
    200199
    201200                                runThread(this, readyThread);
    202201
    203                                 verify( !preemption_enabled );
     202                                verify( disable_preempt_count > 0 );
    204203
    205204                                //Some actions need to be taken from the kernel
     
    243242void finishRunning(processor * this) with( this->finish ) {
    244243        if( action_code == Release ) {
    245                 verify( !preemption_enabled );
     244                verify( disable_preempt_count > 1 );
    246245                unlock( *lock );
    247246        }
     
    250249        }
    251250        else if( action_code == Release_Schedule ) {
    252                 verify( !preemption_enabled );
     251                verify( disable_preempt_count > 1 );
    253252                unlock( *lock );
    254253                ScheduleThread( thrd );
    255254        }
    256255        else if( action_code == Release_Multi ) {
    257                 verify( !preemption_enabled );
     256                verify( disable_preempt_count > lock_count );
    258257                for(int i = 0; i < lock_count; i++) {
    259258                        unlock( *locks[i] );
     
    287286        this_coroutine = NULL;
    288287        this_thread = NULL;
    289         preemption_enabled = false;
    290288        disable_preempt_count = 1;
    291289        // SKULLDUGGERY: We want to create a context for the processor coroutine
     
    335333        verify( thrd->self_cor.state != Halted );
    336334
    337         verify( !preemption_enabled );
     335        verify( disable_preempt_count > 0 );
    338336
    339337        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    345343        }
    346344
    347         verify( !preemption_enabled );
     345        verify( disable_preempt_count > 0 );
    348346}
    349347
    350348thread_desc * nextThread(cluster * this) with( *this ) {
    351         verify( !preemption_enabled );
     349        verify( disable_preempt_count > 0 );
    352350        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    353351        thread_desc * head = pop_head( ready_queue );
    354352        unlock( ready_queue_lock );
    355         verify( !preemption_enabled );
     353        verify( disable_preempt_count > 0 );
    356354        return head;
    357355}
     
    359357void BlockInternal() {
    360358        disable_interrupts();
    361         verify( !preemption_enabled );
    362         suspend();
    363         verify( !preemption_enabled );
     359        verify( disable_preempt_count > 0 );
     360        suspend();
     361        verify( disable_preempt_count > 0 );
    364362        enable_interrupts( __cfaabi_dbg_ctx );
    365363}
     
    370368        this_processor->finish.lock        = lock;
    371369
    372         verify( !preemption_enabled );
    373         suspend();
    374         verify( !preemption_enabled );
     370        verify( disable_preempt_count > 1 );
     371        suspend();
     372        verify( disable_preempt_count > 0 );
    375373
    376374        enable_interrupts( __cfaabi_dbg_ctx );
     
    382380        this_processor->finish.thrd        = thrd;
    383381
    384         verify( !preemption_enabled );
    385         suspend();
    386         verify( !preemption_enabled );
     382        verify( disable_preempt_count > 0 );
     383        suspend();
     384        verify( disable_preempt_count > 0 );
    387385
    388386        enable_interrupts( __cfaabi_dbg_ctx );
     
    396394        this_processor->finish.thrd        = thrd;
    397395
    398         verify( !preemption_enabled );
    399         suspend();
    400         verify( !preemption_enabled );
     396        verify( disable_preempt_count > 1 );
     397        suspend();
     398        verify( disable_preempt_count > 0 );
    401399
    402400        enable_interrupts( __cfaabi_dbg_ctx );
     
    409407        this_processor->finish.lock_count  = count;
    410408
    411         verify( !preemption_enabled );
    412         suspend();
    413         verify( !preemption_enabled );
     409        verify( disable_preempt_count > 0 );
     410        suspend();
     411        verify( disable_preempt_count > 0 );
    414412
    415413        enable_interrupts( __cfaabi_dbg_ctx );
     
    424422        this_processor->finish.thrd_count  = thrd_count;
    425423
    426         verify( !preemption_enabled );
    427         suspend();
    428         verify( !preemption_enabled );
     424        verify( disable_preempt_count > 0 );
     425        suspend();
     426        verify( disable_preempt_count > 0 );
    429427
    430428        enable_interrupts( __cfaabi_dbg_ctx );
     
    432430
    433431void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    434         verify( !preemption_enabled );
     432        verify( disable_preempt_count > 0 );
    435433        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    436434        this_processor->finish.lock        = lock;
  • src/libcfa/concurrency/kernel_private.h

    r3ce0c915 r11b7028  
    7474
    7575extern volatile thread_local bool preemption_in_progress;
    76 extern volatile thread_local bool preemption_enabled;
    7776extern volatile thread_local unsigned short disable_preempt_count;
    7877
  • src/libcfa/concurrency/monitor.c

    r3ce0c915 r11b7028  
    8787                thread_desc * thrd = this_thread;
    8888
     89                verify( disable_preempt_count > 0 );
     90
    8991                __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
    9092
     
    115117                        // Some one else has the monitor, wait in line for it
    116118                        append( this->entry_queue, thrd );
     119
     120                        verify( disable_preempt_count > 0 );
    117121
    118122                        BlockInternal( &this->lock );
     
    392396        append( this.blocked, &waiter );
    393397
     398        verify( disable_preempt_count == 0 );
     399
    394400        // Lock all monitors (aggregates the locks as well)
    395401        lock_all( monitors, locks, count );
     402
     403        // verifyf( disable_preempt_count == count, "Got %d, expected %d\n", disable_preempt_count, count );
     404        if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); }
    396405
    397406        // Find the next thread(s) to run
     
    468477        monitor_ctx( this.monitors, this.monitor_count );
    469478
     479        verify( disable_preempt_count == 0 );
     480
    470481        // Lock all monitors (aggregates the locks them as well)
    471482        lock_all( monitors, locks, count );
     483
     484        // verify( disable_preempt_count == count );
     485        if(disable_preempt_count != count) { __cfaabi_dbg_print_buffer_decl("----------Gonna crash\n"); }
    472486
    473487
  • src/libcfa/concurrency/preemption.c

    r3ce0c915 r11b7028  
    4949// Machine specific register name
    5050#if   defined(__x86_64__)
    51 #define CFA_REG_IP gregs[REG_RIP]
     51#define CFA_REG_IP REG_RIP
    5252#elif defined(__i386__)
    53 #define CFA_REG_IP gregs[REG_EIP]
     53#define CFA_REG_IP REG_EIP
    5454#elif defined(__ARM_ARCH__)
    55 #define CFA_REG_IP arm_pc
     55#define CFA_REG_IP REG_R15
    5656#endif
    5757
     
    142142        // Disable interrupts by incrementing the counter
    143143        void disable_interrupts() {
    144                 preemption_enabled = false;
    145                 __attribute__((unused)) unsigned short new_val = disable_preempt_count + 1;
    146                 disable_preempt_count = new_val;
     144                __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST );
    147145                verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
    148146        }
     
    154152                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
    155153
    156                 unsigned short prev = disable_preempt_count;
    157                 disable_preempt_count -= 1;
     154                unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    158155                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
    159156
    160157                // Check if we need to prempt the thread because an interrupt was missed
    161                 if( prev == 1 ) {
    162                         preemption_enabled = true;
    163                         if( proc->pending_preemption ) {
    164                                 proc->pending_preemption = false;
    165                                 BlockInternal( thrd );
    166                         }
     158                if( prev == 1 && proc->pending_preemption ) {
     159                        proc->pending_preemption = false;
     160                        BlockInternal( thrd );
    167161                }
    168162
     
    174168        // Don't execute any pending CtxSwitch even if counter reaches 0
    175169        void enable_interrupts_noPoll() {
    176                 unsigned short prev = disable_preempt_count;
    177                 disable_preempt_count -= 1;
     170                __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST );
    178171                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    179                 if( prev == 1 ) {
    180                         preemption_enabled = true;
    181                 }
    182172        }
    183173}
     
    220210// If false : preemption is unsafe and marked as pending
    221211static inline bool preemption_ready() {
    222         bool ready = preemption_enabled && !preemption_in_progress; // Check if preemption is safe
     212        bool ready = disable_preempt_count == 0 && !preemption_in_progress; // Check if preemption is safe
    223213        this_processor->pending_preemption = !ready;                        // Adjust the pending flag accordingly
    224214        return ready;
     
    235225
    236226        // Start with preemption disabled until ready
    237         preemption_enabled = false;
    238227        disable_preempt_count = 1;
    239228
     
    295284// Receives SIGUSR1 signal and causes the current thread to yield
    296285void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    297         __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); )
    298 
    299         // Check if it is safe to preempt here
     286#if defined( __ARM_ARCH )
     287        __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.arm_pc); )
     288#else
     289        __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )
     290#endif
     291
     292                // Check if it is safe to preempt here
    300293        if( !preemption_ready() ) { return; }
    301294
Note: See TracChangeset for help on using the changeset viewer.