[PATCH 7/9] termios: SMP support

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Jun 10 13:11:55 UTC 2013


---
 cpukit/libcsupport/include/rtems/termiostypes.h |    8 ++++
 cpukit/libcsupport/src/termios.c                |   46 ++++++++++++-----------
 2 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index 89a997a..4f69191 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -140,6 +140,8 @@ struct rtems_termios_tty {
   struct ttywakeup tty_snd;
   struct ttywakeup tty_rcv;
   int              tty_rcvwakeup;
+
+  rtems_interrupt_lock interrupt_lock;
 };
 
 struct rtems_termios_linesw {
@@ -231,6 +233,12 @@ int rtems_termios_set_initial_baud(
   rtems_termios_baud_t baud
 );
 
+#define rtems_termios_interrupt_lock_acquire(tty, level) \
+  rtems_interrupt_lock_acquire(&tty->interrupt_lock, level)
+
+#define rtems_termios_interrupt_lock_release(tty, level) \
+  rtems_interrupt_lock_release(&tty->interrupt_lock, level)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index c13f331..6efeab2 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -230,6 +230,8 @@ rtems_termios_open (
      */
     tty->device = *callbacks;
 
+    rtems_interrupt_lock_initialize (&tty->interrupt_lock);
+
     /*
      * Create I/O tasks
      */
@@ -340,17 +342,17 @@ drainOutput (struct rtems_termios_tty *tty)
   rtems_status_code sc;
 
   if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
-    rtems_interrupt_disable (level);
+    rtems_termios_interrupt_lock_acquire (tty, level);
     while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
       tty->rawOutBufState = rob_wait;
-      rtems_interrupt_enable (level);
+      rtems_termios_interrupt_lock_release (tty, level);
       sc = rtems_semaphore_obtain(
         tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
       if (sc != RTEMS_SUCCESSFUL)
         rtems_fatal_error_occurred (sc);
-      rtems_interrupt_disable (level);
+      rtems_termios_interrupt_lock_acquire (tty, level);
     }
-    rtems_interrupt_enable (level);
+    rtems_termios_interrupt_lock_release (tty, level);
   }
 }
 
@@ -359,11 +361,11 @@ flushOutput (struct rtems_termios_tty *tty)
 {
   rtems_interrupt_level level;
 
-  rtems_interrupt_disable (level);
+  rtems_termios_interrupt_lock_acquire (tty, level);
   tty->rawOutBuf.Tail = 0;
   tty->rawOutBuf.Head = 0;
   tty->rawOutBufState = rob_idle;
-  rtems_interrupt_enable (level);
+  rtems_termios_interrupt_lock_release (tty, level);
 }
 
 static void
@@ -371,10 +373,10 @@ flushInput (struct rtems_termios_tty *tty)
 {
   rtems_interrupt_level level;
 
-  rtems_interrupt_disable (level);
+  rtems_termios_interrupt_lock_acquire (tty, level);
   tty->rawInBuf.Tail = 0;
   tty->rawInBuf.Head = 0;
-  rtems_interrupt_enable (level);
+  rtems_termios_interrupt_lock_release (tty, level);
 }
 
 rtems_status_code
@@ -481,7 +483,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
     /* has output been stopped due to received XOFF? */
     if (tty->flow_ctrl & FL_OSTOP) {
       /* disable interrupts    */
-      rtems_interrupt_disable(level);
+      rtems_termios_interrupt_lock_acquire (tty, level);
       tty->flow_ctrl &= ~FL_OSTOP;
       /* check for chars in output buffer (or rob_state?) */
       if (tty->rawOutBufState != rob_idle) {
@@ -490,7 +492,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
           tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
       }
       /* reenable interrupts */
-      rtems_interrupt_enable(level);
+      rtems_termios_interrupt_lock_release (tty, level);
     }
   }
   /* check for incoming XON/XOFF flow control switched off */
@@ -571,7 +573,7 @@ rtems_termios_select (struct rtems_termios_tty *tty,
   int rv = 0;
 
   rtems_interrupt_level level;
-  rtems_interrupt_disable(level);
+  rtems_termios_interrupt_lock_acquire (tty, level);
   switch (request->kind) {
     case RTEMS_IOCTL_SELECT_READ:
       if (rtems_termios_can_read (tty)) {
@@ -593,7 +595,7 @@ rtems_termios_select (struct rtems_termios_tty *tty,
     default:
       break;
   }
-  rtems_interrupt_enable(level);
+  rtems_termios_interrupt_lock_release (tty, level);
 
   return rv;
 }
@@ -763,15 +765,15 @@ rtems_termios_puts (
      * with interrupts enabled.
      */
     newHead = (newHead + 1) % tty->rawOutBuf.Size;
-    rtems_interrupt_disable (level);
+    rtems_termios_interrupt_lock_acquire (tty, level);
     while (newHead == tty->rawOutBuf.Tail) {
       tty->rawOutBufState = rob_wait;
-      rtems_interrupt_enable (level);
+      rtems_termios_interrupt_lock_release (tty, level);
       sc = rtems_semaphore_obtain(
         tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
       if (sc != RTEMS_SUCCESSFUL)
         rtems_fatal_error_occurred (sc);
-      rtems_interrupt_disable (level);
+      rtems_termios_interrupt_lock_acquire (tty, level);
     }
     tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
     tty->rawOutBuf.Head = newHead;
@@ -786,7 +788,7 @@ rtems_termios_puts (
       }
       tty->rawOutBufState = rob_busy;
     }
-    rtems_interrupt_enable (level);
+    rtems_termios_interrupt_lock_release (tty, level);
     len--;
   }
 }
@@ -1288,7 +1290,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
       /* restart output according to FL_ORCVXOF flag */
       if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
         /* disable interrupts    */
-        rtems_interrupt_disable(level);
+        rtems_termios_interrupt_lock_acquire (tty, level);
         tty->flow_ctrl &= ~FL_OSTOP;
         /* check for chars in output buffer (or rob_state?) */
         if (tty->rawOutBufState != rob_idle) {
@@ -1297,12 +1299,12 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
             tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
         }
         /* reenable interrupts */
-        rtems_interrupt_enable(level);
+        rtems_termios_interrupt_lock_release (tty, level);
       }
     } else {
       newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
       /* if chars_in_buffer > highwater                */
-      rtems_interrupt_disable(level);
+      rtems_termios_interrupt_lock_acquire (tty, level);
       if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
             % tty->rawInBuf.Size) > tty->highwater) &&
           !(tty->flow_ctrl & FL_IREQXOF)) {
@@ -1328,7 +1330,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
       }
 
       /* reenable interrupts */
-      rtems_interrupt_enable(level);
+      rtems_termios_interrupt_lock_release (tty, level);
 
       if (newTail == tty->rawInBuf.Head) {
         dropped++;
@@ -1365,7 +1367,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
   rtems_interrupt_level level;
   int len;
 
-  rtems_interrupt_disable(level);
+  rtems_termios_interrupt_lock_acquire (tty, level);
 
   /* check for XOF/XON to send */
   if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
@@ -1464,7 +1466,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
     tty->rawOutBuf.Tail = newTail; /*apm*/
   }
 
-  rtems_interrupt_enable(level);
+  rtems_termios_interrupt_lock_release (tty, level);
 
   if (wakeUpWriterTask) {
     rtems_semaphore_release (tty->rawOutBuf.Semaphore);
-- 
1.7.7




More information about the devel mailing list