avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-dev] New Atomic.h header?


From: Dean
Subject: [avr-libc-dev] New Atomic.h header?
Date: Sun, 7 Jan 2007 17:18:21 +1100

Hi guys!

There was a recent discussion on 'Freaks covering atomic blocks of code, ie. 
code blocks which for their duration have interrupts disabled:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=45041

Many different suggestions were made, from simple macros to more complex and 
fool-proof methods. I eventually came up with heavily modified versions of 
Darcy Watkin's macro posted at:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37733&highlight=atomic+macro

My macro allows for both atomic (interrupts disabled) and non-atomic 
(interrupts enabled) blocks of code to be easily made. Unlike conventional 
methods these macros are quite foolproof - the epilogue for each is run 
automatically on block exit regardless of the exit path. When compiled with 
-Os, it results in the smallest possible code.

Two options are avaliable; ATOMIC_RESTORESTATE, where the previous interrupt 
enable flag status is restored, and ATOMIC_FORCEON (or ATOMIC_FORCEOFF for the 
non-atomic block) which forces the global flag state on block exit - desirable 
in some instances.

Despite its simplicity, would it have an application for AVRLibC? Should I add 
DoxyGen comments and submit as a patch?

================================================

#ifndef ATOMIC_H
#define ATOMIC_H

 #include <avr/io.h>
 #include <avr/interrupt.h>

 static inline void    __iSeiParam(const uint8_t *s)  { sei(); (void)s; }
 static inline void    __iCliParam(const uint8_t *s)  { cli(); (void)s; }
 static inline uint8_t __iSeiRetVal(void)             { sei(); return 1; }   
 static inline uint8_t __iCliRetVal(void)             { cli(); return 1; }   
 static inline void    __iRestore(const uint8_t *s)   { SREG = *s; }

 #define ATOMIC_BLOCK(exitmode)     for ( exitmode, __ToDo = __iCliRetVal(); 
__ToDo ; __ToDo = 0 )

 #define ATOMIC_RESTORESTATE        uint8_t sreg_save 
__attribute__((__cleanup__(__iRestore))) = SREG
 #define ATOMIC_FORCEON             uint8_t sreg_save 
__attribute__((__cleanup__(__iSeiParam))) = 0
 
 #define NON_ATOMIC_BLOCK(type)     for ( type, __ToDo = __iSeiRetVal(); __ToDo 
; __ToDo = 0 )
 
 #define NONATOMIC_RESTORESTATE     uint8_t sreg_save 
__attribute__((__cleanup__(__iRestore))) = SREG
 #define NONATOMIC_FORCEOFF         uint8_t sreg_save 
__attribute__((__cleanup__(__iCliParam))) = 0

#endif

================================================


reply via email to

[Prev in Thread] Current Thread [Next in Thread]