This is the mail archive of the crossgcc@cygnus.com mailing list for the crossgcc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Atomic Operations (continuing on from Masking Interrupts?)


>>>>> "David" == David Querbach <querbach@realtime.bc.ca> writes:

    >> The fix for this problem is to have a counter that increments
    >> on disable, and decrements on enable.  The enable routine will
    >> only actually enable interrupts if the value of the counter is
    >> zero.  We must make sure that the increment and decrement
    >> operations are also atomic; therefore, we must actually disable
    >> interrupts before the counter is incremented in
    >> assembler_routine_to_disable_interrupts(), and decrement before
    >> we disable interrupts in
    >> assembler_routine_to_enable_interrupts() (we realize, of
    >> course, that it is an error to call
    >> assembler_routine_to_enable_interrupts() when interrupts are
    >> not disabled!), and only actually enable interrupts in
    >> assembler_routine_to_enable_interrupts() is the counter goes to
    >> zero.  The counter must be global in C, but should probably be
    >> class static in C++.

    David> In our system, we have a target-dependent header file that
    David> defines four macros:

    David>   - enableInts() unconditionally enables interrupts

    David>   - disableInts() unconditionally disables interrupts

    David>   - inhibitInts() saves the CPU's interrupt mask bit in an
    David> auto variable, then invokes disableInts()

    David>   - restoreInts() sets the CPU's interrupt mask bit from
    David> the auto variable written by inhibitInts().

    David> This method isn't perfect, but it does allow inhibiting
    David> interrupts deep in a library without interfering with the
    David> application's interrupt enable/disable status.  Also, since
    David> we have such a file for each processor, interrupt mask
    David> handling becomes portable.

The problem is that there is no language enforced way to insure that
enables are balanced with disables, and inhibits are balanced with
restores.  The use of a subroutine that takes a thunk as its sole
argument, such as my "without_pre_emption(thunk)" example above,
forces the programmer to keep things balanced.  The only real
trouble-maker is throwing an exception, or taking a longjump.  Lisp
provides "unwind-protect" for that situation.

-- 
--------  "And there came a writing to him from Elijah"  [2Ch 21:12]  --------
R. J. Brown III  rj@elilabs.com http://www.elilabs.com/~rj  voice 847 543-4060
Elijah Laboratories Inc. 457 Signal Lane, Grayslake IL 60030  fax 847 543-4061
-----  M o d e l i n g   t h e   M e t h o d s   o f   t h e   M i n d  ------
_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]