فهرست منبع

修改结构名称,修复一些bug

linzhenxing 3 سال پیش
والد
کامیت
9e8badabbe

+ 2 - 1
components/drivers/tty/console.c

@@ -295,13 +295,14 @@ rt_err_t console_register(const char *name, struct rt_device *iodev)
     console->type = TTY_DRIVER_TYPE_CONSOLE;
     console->subtype = SERIAL_TYPE_NORMAL;
     console->driver = iodev;
-    console->head = rt_calloc(1, sizeof(struct list_node));
+    console->head = rt_calloc(1, sizeof(struct tty_node));
     if (!console->head)
     {
         return -RT_ENOMEM;
     }
     tty_initstack(console->head);
 
+    rt_mutex_init(&console->mutex, "console", RT_IPC_FLAG_PRIO);
     console->pgrp = -1;
     console->session = -1;
     console->foreground = RT_NULL;

+ 7 - 7
components/drivers/tty/include/tty.h

@@ -23,15 +23,15 @@
 #define current lwp_self()
 #define __DISABLED_CHAR '\0'
 
-struct list_node
+struct tty_node
 {
-    struct rt_lwp *p;
-    struct list_node *next;
+    struct rt_lwp *lwp;
+    struct tty_node *next;
 };
 
-void tty_initstack(struct list_node *node);
-int tty_push(struct list_node **head, struct rt_lwp *lwp);
-struct rt_lwp *tty_pop(struct list_node **head);
+void tty_initstack(struct tty_node *node);
+int tty_push(struct tty_node **head, struct rt_lwp *lwp);
+struct rt_lwp *tty_pop(struct tty_node **head, struct rt_lwp *target_lwp);
 /*
  * When a break, frame error, or parity error happens, these codes are
  * stuffed into the flags buffer.
@@ -153,7 +153,7 @@ struct tty_struct
     pid_t pgrp;
     pid_t session;
     struct rt_lwp *foreground;
-    struct list_node *head;
+    struct tty_node *head;
 
     struct tty_ldisc *ldisc;
     void *disc_data;

+ 1 - 1
components/drivers/tty/n_tty.c

@@ -547,7 +547,7 @@ static void __isig(int sig, struct tty_struct *tty)
                 }
             }
             tty_sigaddset(&lwp->signal_mask, SIGTTOU);
-            old_lwp = tty_pop(&tty->head);
+            old_lwp = tty_pop(&tty->head, RT_NULL);
             tty->foreground = old_lwp;  
         }
         else

+ 3 - 2
components/drivers/tty/pty.c

@@ -341,13 +341,14 @@ static int ptmx_register(void)
 
     ptm_drv->type = TTY_DRIVER_TYPE_PTY;
     ptm_drv->subtype = PTY_TYPE_MASTER;
-    ptm_drv->head = rt_calloc(1, sizeof(struct list_node));
+    ptm_drv->head = rt_calloc(1, sizeof(struct tty_node));
     if (!ptm_drv->head)
     {
         return -RT_ENOMEM;
     }
     tty_initstack(ptm_drv->head);
-    
+
+    rt_mutex_init(&ptm_drv->mutex, "pty", RT_IPC_FLAG_PRIO);
     ptm_drv->pgrp = -1;
     ptm_drv->session = -1;
     ptm_drv->foreground = RT_NULL;

+ 65 - 17
components/drivers/tty/tty.c

@@ -38,41 +38,89 @@ struct termios tty_std_termios = {  /* for the benefit of tty drivers  */
     .__c_ospeed = 38400
 };
 
-void tty_initstack(struct list_node *node)
+void tty_initstack(struct tty_node *node)
 {
-    node->p = NULL;
+    node->lwp = RT_NULL;
     node->next = node;
 }
 
-int tty_push(struct list_node **head, struct rt_lwp *lwp)
+static struct tty_node tty_node_cache = { RT_NULL, RT_NULL };
+
+static struct tty_node *_tty_node_alloc(void)
+{
+    struct tty_node *node = tty_node_cache.next;
+
+    if (node == RT_NULL)
+    {
+        node = rt_calloc(1, sizeof(struct tty_node));
+    }
+    else
+    {
+        tty_node_cache.next = node->next;
+    }
+
+    return node;
+}
+
+static void _tty_node_free(struct tty_node *node)
+{
+    node->next = tty_node_cache.next;
+    tty_node_cache.next = node;
+}
+
+int tty_push(struct tty_node **head, struct rt_lwp *lwp)
 {
-    struct list_node *s = rt_calloc(1, sizeof(struct list_node));
-    if (!s)
+    struct tty_node *node = _tty_node_alloc();
+
+    if (!node)
     {
         return -1;
     }
-    s->p = lwp;
-    s->next = *head;
-    *head = s;
+
+    node->lwp = lwp;
+    node->next = *head;
+    *head = node;
 
     return 0;
 }
 
-struct rt_lwp *tty_pop(struct list_node **head)
+struct rt_lwp *tty_pop(struct tty_node **head, struct rt_lwp *target_lwp)
 {
-    struct list_node *s;
-    struct rt_lwp *lwp;
+    struct tty_node *node;
+    struct rt_lwp *lwp = RT_NULL;
 
-    if (!*head)
+    if (!head || !*head)
     {
         return RT_NULL;
     }
 
-    lwp = (*head)->p;
-    s = *head;
-    *head = (*head)->next;
-    s->p = NULL;
-    rt_free(s);
+    node = *head;
+
+    if (target_lwp != RT_NULL && node->lwp != target_lwp)
+    {
+        struct tty_node *prev = RT_NULL;
+
+        while (node != RT_NULL && node->lwp != target_lwp)
+        {
+            prev = node;
+            node = node->next;
+        }
+
+        if (node != RT_NULL)
+        {
+            /* prev is impossible equ RT_NULL */
+            prev->next = node->next;
+            lwp = target_lwp;
+            _tty_node_free(node);
+        }
+    }
+    else
+    {
+        lwp = (*head)->lwp;
+        *head = (*head)->next;
+        node->lwp = RT_NULL;
+        _tty_node_free(node);
+    }
 
     return lwp;
 }

+ 11 - 2
components/lwp/lwp.c

@@ -1008,6 +1008,7 @@ void lwp_cleanup(struct rt_thread *tid)
 {
     rt_base_t level;
     struct rt_lwp *lwp;
+    struct tty_node *tty_head;
 
     if (tid == NULL)
     {
@@ -1022,8 +1023,12 @@ void lwp_cleanup(struct rt_thread *tid)
     lwp_tid_put(tid->tid);
     rt_list_remove(&tid->sibling);
     rt_hw_interrupt_enable(level);
-    lwp_ref_dec(lwp);
-
+    tty_head = lwp->tty->head;
+    if (!lwp_ref_dec(lwp))
+    {
+        tty_pop(&tty_head, lwp);
+    }
+    
     return;
 }
 
@@ -1205,11 +1210,13 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
                     struct rt_lwp *old_lwp;
                     tty = (struct tty_struct *)console_tty_get();
                     old_lwp = tty->foreground;
+                    rt_mutex_take(&tty->mutex, RT_WAITING_FOREVER);
                     ret = tty_push(&tty->head, old_lwp);
                     if (ret < 0)
                     {
                         rt_kprintf("malloc fail!\n");
                     }
+                    rt_mutex_release(&tty->mutex);
                     lwp->tty = tty;
                     lwp->tty->pgrp = lwp->__pgrp;
                     lwp->tty->session = lwp->session;
@@ -1223,11 +1230,13 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
                 {
                     if (self_lwp != RT_NULL)
                     {
+                        rt_mutex_take(&self_lwp->tty->mutex, RT_WAITING_FOREVER);
                         ret = tty_push(&self_lwp->tty->head, self_lwp);
                         if (ret < 0)
                         {
                             rt_kprintf("malloc fail!\n");
                         }
+                        rt_mutex_release(&self_lwp->tty->mutex);
                         lwp->tty = self_lwp->tty;
                         lwp->tty->pgrp = lwp->__pgrp;
                         lwp->tty->session = lwp->session;

+ 11 - 4
components/lwp/lwp_pid.c

@@ -447,8 +447,9 @@ void lwp_free(struct rt_lwp* lwp)
         level = rt_hw_interrupt_disable();
         if (lwp->tty != RT_NULL)
         {
-            old_lwp = tty_pop(&lwp->tty->head);
-
+            rt_mutex_take(&lwp->tty->mutex, RT_WAITING_FOREVER);
+            old_lwp = tty_pop(&lwp->tty->head, RT_NULL);
+            rt_mutex_release(&lwp->tty->mutex);
             if (lwp->tty->foreground == lwp)
             {
                 lwp->tty->foreground = old_lwp;
@@ -485,16 +486,18 @@ void lwp_free(struct rt_lwp* lwp)
     }
 }
 
-void lwp_ref_inc(struct rt_lwp *lwp)
+int lwp_ref_inc(struct rt_lwp *lwp)
 {
     rt_base_t level;
 
     level = rt_hw_interrupt_disable();
     lwp->ref++;
     rt_hw_interrupt_enable(level);
+
+    return 0;
 }
 
-void lwp_ref_dec(struct rt_lwp *lwp)
+int lwp_ref_dec(struct rt_lwp *lwp)
 {
     rt_base_t level;
     int ref = -1;
@@ -522,7 +525,11 @@ void lwp_ref_dec(struct rt_lwp *lwp)
 #endif /* RT_LWP_USING_SHM */
 #endif /* not defined ARCH_MM_MMU */
         lwp_free(lwp);
+
+        return 0;
     }
+
+    return -1;
 }
 
 struct rt_lwp* lwp_from_pid(pid_t pid)

+ 2 - 2
components/lwp/lwp_pid.h

@@ -22,8 +22,8 @@ struct lwp_avl_struct *lwp_get_pid_ary(void);
 struct rt_lwp* lwp_new(void);
 void lwp_free(struct rt_lwp* lwp);
 
-void lwp_ref_inc(struct rt_lwp *lwp);
-void lwp_ref_dec(struct rt_lwp *lwp);
+int lwp_ref_inc(struct rt_lwp *lwp);
+int lwp_ref_dec(struct rt_lwp *lwp);
 
 struct rt_lwp* lwp_from_pid(pid_t pid);
 pid_t lwp_to_pid(struct rt_lwp* lwp);

+ 2 - 0
components/lwp/lwp_syscall.c

@@ -1729,12 +1729,14 @@ int _sys_fork(void)
         struct rt_lwp *old_lwp;
 
         old_lwp = lwp->tty->foreground;
+        rt_mutex_take(&lwp->tty->mutex, RT_WAITING_FOREVER);
         ret = tty_push(&lwp->tty->head, old_lwp);
         if (ret < 0)
         {
             rt_kprintf("malloc fail!\n");
             goto fail;
         }
+        rt_mutex_release(&lwp->tty->mutex);
         lwp->tty->foreground = lwp;
     }
     rt_hw_interrupt_enable(level);