Change UNUSED() macro to accept two arguments: type and name;
[bertos.git] / mware / fifobuf.h
index e04793aeb7983c1fe5a49f792affcff2104a05d3..194f10dc288678de3c9f3163f2512df8d34509e0 100755 (executable)
 
 /*
  * $Log$
+ * Revision 1.6  2004/06/06 17:18:04  bernie
+ * Remove redundant declaration of fifo_isempty_locked().
+ *
+ * Revision 1.5  2004/06/06 16:50:35  bernie
+ * Import fixes for race conditions from project_ks.
+ *
+ * Revision 1.4  2004/06/06 16:11:17  bernie
+ * Protect MetroWerks specific pragmas with #ifdef's
+ *
  * Revision 1.3  2004/06/03 15:04:10  aleph
  * Merge improvements from project_ks (mainly inlining)
  *
@@ -95,12 +104,15 @@ typedef struct FIFOBuffer
 
 /* Public function prototypes */
 INLINE bool fifo_isempty(const FIFOBuffer *fb);
-INLINE bool fifo_isempty_locked(const FIFOBuffer *fb);
 INLINE bool fifo_isfull(const FIFOBuffer *fb);
 INLINE bool fifo_isfull_locked(const FIFOBuffer *fb);
+#ifdef __MWERKS__
 #pragma interrupt called
+#endif
 INLINE void fifo_push(FIFOBuffer *fb, unsigned char c);
+#ifdef __MWERKS__
 #pragma interrupt called
+#endif
 INLINE unsigned char fifo_pop(FIFOBuffer *fb);
 INLINE void fifo_flush(FIFOBuffer *fb);
 INLINE void fifo_init(FIFOBuffer *fb, unsigned char *buf, size_t size);
@@ -111,7 +123,10 @@ INLINE void fifo_init(FIFOBuffer *fb, unsigned char *buf, size_t size);
  *
  * \note Calling fifo_isempty() is safe while a concurrent
  *       execution context is calling fifo_push() or fifo_pop()
- *       only if the CPU can atomically update a pointer.
+ *       only if the CPU can atomically update a pointer
+ *       (which the AVR and other 8-bit processors can't do).
+ *
+ * \sa fifo_isempty_locked
  */
 INLINE bool fifo_isempty(const FIFOBuffer *fb)
 {
@@ -140,44 +155,6 @@ INLINE bool fifo_isfull(const FIFOBuffer *fb)
 }
 
 
-#if !defined(__AVR__)
-
-       /* No tricks needed on 16/32bit CPUs */
-#      define fifo_isempty_locked(fb) fifo_isempty((fb))
-
-#else /* !__AVR__ */
-
-       INLINE bool fifo_isempty_locked(const FIFOBuffer *fb)
-       {
-               bool result;
-               cpuflags_t flags;
-
-               DISABLE_IRQSAVE(flags);
-               result = fifo_isempty(fb);
-               ENABLE_IRQRESTORE(flags);
-
-               return result;
-       }
-
-#endif /* !__AVR__ */
-
-
-/*!
- * Thread safe version of fifo_isfull()
- */
-INLINE bool fifo_isfull_locked(const FIFOBuffer *_fb)
-{
-       bool _result;
-       cpuflags_t _flags;
-
-       DISABLE_IRQSAVE(_flags);
-       _result = fifo_isfull(_fb);
-       ENABLE_IRQRESTORE(_flags);
-
-       return _result;
-}
-
-
 /*!
  * Pop a character from the fifo buffer.
  *
@@ -186,7 +163,11 @@ INLINE bool fifo_isfull_locked(const FIFOBuffer *_fb)
  *       one free slot before calling this function.
  *
  * \note It is safe to call fifo_pop() and fifo_push() from
- *       concurrent contexts.
+ *       concurrent contexts, unless the CPU can't update
+ *       a pointer atomically (which the AVR and other 8-bit
+ *       processors can't do).
+ *
+ * \sa fifo_push_locked
  */
 INLINE void fifo_push(FIFOBuffer *fb, unsigned char c)
 {
@@ -235,6 +216,70 @@ INLINE void fifo_flush(FIFOBuffer *fb)
 }
 
 
+#if !defined(__AVR__)
+
+       /* No tricks needed on 16/32bit CPUs */
+#      define fifo_isempty_locked(fb) fifo_isempty((fb))
+#      define fifo_push_locked(fb, c) fifo_push((fb), (c))
+
+#else /* !__AVR__ */
+
+       /*!
+        * Similar to fifo_isempty(), but with stronger guarantees for
+        * concurrent access between user and interrupt code.
+        * This is actually only needed for 8-bit processors.
+        *
+        * \sa fifo_isempty()
+        */
+       INLINE bool fifo_isempty_locked(const FIFOBuffer *fb);
+       INLINE bool fifo_isempty_locked(const FIFOBuffer *fb)
+       {
+               bool result;
+               cpuflags_t flags;
+
+               DISABLE_IRQSAVE(flags);
+               result = fifo_isempty(fb);
+               ENABLE_IRQRESTORE(flags);
+
+               return result;
+       }
+
+       /*!
+        * Similar to fifo_push(), but with stronger guarantees for
+        * concurrent access between user and interrupt code.
+        * This is actually only needed for 8-bit processors.
+        *
+        * \sa fifo_push()
+        */
+       INLINE void fifo_push_locked(FIFOBuffer *fb, unsigned char c);
+       INLINE void fifo_push_locked(FIFOBuffer *fb, unsigned char c)
+       {
+               cpuflags_t flags;
+               DISABLE_IRQSAVE(flags);
+               fifo_push(fb, c);
+               ENABLE_IRQRESTORE(flags);
+       }
+
+#endif /* !__AVR__ */
+
+
+/*!
+ * Thread safe version of fifo_isfull()
+ */
+INLINE bool fifo_isfull_locked(const FIFOBuffer *_fb)
+{
+       bool _result;
+       cpuflags_t _flags;
+
+       DISABLE_IRQSAVE(_flags);
+       _result = fifo_isfull(_fb);
+       ENABLE_IRQRESTORE(_flags);
+
+       return _result;
+}
+
+
+
 /*!
  * FIFO Initialization.
  */