# Changes in /[06b176d:41fcd94]

Ignore:
Files:
4 edited

Unmodified
Removed
• ## doc/papers/general/Paper.tex

 r06b176d In \CFA, the address of a @T&@ is a lvalue @T*@, as the address of the underlying @T@ is stored in the reference, and can thus be mutated there. The result of this rule is that any reference can be rebound using the existing pointer assignment semantics by assigning a compatible pointer into the address of the reference, \eg @&r1 = &x;@ above. This rebinding can occur to an arbitrary depth of reference nesting; $n$ address-of operators applied to a reference nested $m$ times will produce an lvalue pointer nested $n$ times if $n \le m$ (note that $n = m+1$ is simply the usual C rvalue address-of operator applied to the $n = m$ case). The explicit address-of operators can be thought of as cancelling out'' the implicit dereference operators, \eg @(&*)r1 = &x@ or @(&(&*)*)r3 = &(&*)r1@ or even @(&*)r2 = (&*)*r3@ for @&r2 = &r3@. This rebinding can occur to an arbitrary depth of reference nesting; loosely speaking, nested address-of operators will produce an lvalue nested pointer up to as deep as the reference they're applied to. These explicit address-of operators can be thought of as cancelling out'' the implicit dereference operators, \eg @(&*)r1 = &x@ or @(&(&*)*)r3 = &(&*)r1@ or even @(&*)r2 = (&*)*r3@ for @&r2 = &r3@. More precisely: \begin{itemize} \item if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) than @&R@ has type {@T *&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols). \item if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T *&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols). \end{itemize} Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them in user code can be made based solely on convenience. In particular, \CFA does not implement class-based encapsulation: neither the constructor nor any other function has privileged access to the implementation details of a type, except through the translation-unit-scope method of opaque structs provided by C. In \CFA, a constructor is a function named @?{}@, while a destructor is a function named @^?{}@; like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @S s = { ... };@ or @^(s){};@. In \CFA, a constructor is a function named @?{}@, while a destructor is a function named @^?{}@; like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @x{ ... };@ or @^x{};@. Every constructor and destructor must have a return type of @void@, and its first parameter must have a reference type whose base type is the type of the object the function constructs or destructs. This first parameter is informally called the @this@ parameter, as in many object-oriented languages, though a programmer may give it an arbitrary name. \begin{cfa} Array a, b; (a){};                                  $\C{// default construct}$ (b){ a };                               $\C{// copy construct}$ ^(a){};                                 $\C{// destruct}$ (a){ 5, 0xFFFFFFFF };   $\C{// explicit constructor call}$ a{};                            $\C{// default construct}$ b{ a };                         $\C{// copy construct}$ ^a{};                           $\C{// destruct}$ a{ 5, 0xFFFFFFFF };     $\C{// explicit constructor call}$ \end{cfa}
• ## src/libcfa/concurrency/kernel.c

 r06b176d if( ! do_terminate ) { __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); do_terminate = true; terminate(&this); P( terminated ); pthread_join( kernel_thread, NULL );
• ## src/libcfa/concurrency/kernel_private.h

 r06b176d void runThread(processor * this, thread_desc * dst); void finishRunning(processor * this); void terminate(processor * this); void spin(processor * this, unsigned int * spin_count);
• ## src/libcfa/concurrency/preemption.c

 r06b176d } enum { PREEMPT_NORMAL    = 0, PREEMPT_TERMINATE = 1, }; //============================================================================================= // Kernel Preemption logic // kill wrapper : signal a processor static void preempt( processor * this ) { pthread_kill( this->kernel_thread, SIGUSR1 ); sigval_t value = { PREEMPT_NORMAL }; pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); } // kill wrapper : signal a processor void terminate(processor * this) { this->do_terminate = true; sigval_t value = { PREEMPT_TERMINATE }; pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); } void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); ) // SKULLDUGGERY: if a thread creates a processor and the immediately deletes it, // the interrupt that is supposed to force the kernel thread to preempt might arrive // before the kernel thread has even started running. When that happens an iterrupt // we a null 'this_processor' will be caught, just ignore it. if(!this_processor) return; choose(sfp->si_value.sival_int) { case PREEMPT_NORMAL   : ;// Normal case, nothing to do here case PREEMPT_TERMINATE: verify(this_processor->do_terminate); default: abortf( "internal error, signal value is %d", sfp->si_value.sival_int ); } // Check if it is safe to preempt here
Note: See TracChangeset for help on using the changeset viewer.