Просмотр исходного кода

[ctime] fixup of data racing (#8187)

Signed-off-by: Shell <smokewood@qq.com>
Shell 1 год назад
Родитель
Сommit
eafb04e011
3 измененных файлов с 26 добавлено и 15 удалено
  1. 19 8
      components/libc/compilers/common/ctime.c
  2. 1 1
      components/lwp/lwp_ipc.c
  3. 6 6
      include/rtthread.h

+ 19 - 8
components/libc/compilers/common/ctime.c

@@ -24,6 +24,7 @@
  *                             adapt to new api and do the signal handling in thread context
  * 2023-08-12     Meco Man     re-implement RT-Thread lightweight timezone API
  * 2023-09-15     xqyjlj       perf rt_hw_interrupt_disable/enable
+ * 2023-10-23     Shell        add lock for _g_timerid
  */
 
 #include "sys/time.h"
@@ -880,6 +881,7 @@ static void rtthread_timer_wrapper(void *timerobj)
 }
 
 #define TIMER_ID_MAX 50
+static struct rt_spinlock _timer_id_lock = RT_SPINLOCK_INIT;
 static struct timer_obj *_g_timerid[TIMER_ID_MAX];
 static void *timer_id[TIMER_ID_MAX];
 static resource_id_t id_timer = RESOURCE_ID_INIT(TIMER_ID_MAX, timer_id);
@@ -975,8 +977,14 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
     _timerid = resource_id_get(&id_timer);
     if (_timerid < 0)
     {
-        LOG_E("_timerid overflow!");
-        return -1; /* todo:memory leak */
+#ifdef RT_USING_SMART
+        rt_free(param);
+#endif /* RT_USING_SMART */
+
+        rt_ktime_hrtimer_detach(&timer->hrtimer);
+        rt_free(timer);
+        rt_set_errno(ENOMEM);
+        return -1;
     }
     _g_timerid[_timerid] = timer;
 
@@ -1005,17 +1013,20 @@ int timer_delete(timer_t timerid)
         return -1;
     }
 
-    if (_g_timerid[ktimerid] == NULL)
+    RT_DEBUG_NOT_IN_INTERRUPT;
+    rt_spin_lock(&_timer_id_lock);
+    timer = _g_timerid[ktimerid];
+    if (timer != NULL)
     {
-        rt_set_errno(EINVAL);
-        LOG_E("can not find timer!");
-        return -1;
+        _g_timerid[ktimerid] = RT_NULL;
+        resource_id_put(&id_timer, ktimerid);
     }
-    timer = _g_timerid[ktimerid];
-    resource_id_put(&id_timer, ktimerid);
+    rt_spin_unlock(&_timer_id_lock);
+
     if (timer == RT_NULL)
     {
         rt_set_errno(EINVAL);
+        LOG_D("can not find timer %ld", ktimerid);
         return -1;
     }
 

+ 1 - 1
components/lwp/lwp_ipc.c

@@ -55,7 +55,7 @@ static rt_ipc_msg_t _ipc_msg_free_list = (rt_ipc_msg_t)RT_NULL; /* released chai
 static int rt_ipc_msg_used = 0;                                 /* first unallocated entry */
 static struct rt_ipc_msg ipc_msg_pool[RT_CH_MSG_MAX_NR];        /* initial message array */
 
-static rt_spinlock_t ipc_big_lock;
+static struct rt_spinlock ipc_big_lock;
 #define ipc_list_lock   ipc_big_lock
 #define ipc_ch_lock     ipc_big_lock
 

+ 6 - 6
include/rtthread.h

@@ -544,8 +544,8 @@ rt_thread_t rt_thread_defunct_dequeue(void);
 /*
  * spinlock
  */
-#ifdef RT_USING_SMP
 struct rt_spinlock;
+#ifdef RT_USING_SMP
 
 void rt_spin_lock_init(struct rt_spinlock *lock);
 void rt_spin_lock(struct rt_spinlock *lock);
@@ -553,11 +553,11 @@ void rt_spin_unlock(struct rt_spinlock *lock);
 rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock);
 void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level);
 #else
-#define rt_spin_lock_init(lock)                  { RT_UNUSED(lock);                                 }
-#define rt_spin_lock(lock)                       { RT_UNUSED(lock);                                 }
-#define rt_spin_unlock(lock)                     { RT_UNUSED(lock);                                 }
-#define rt_spin_lock_irqsave(lock)              ({ RT_UNUSED(lock); rt_hw_interrupt_disable();      })
-#define rt_spin_unlock_irqrestore(lock, level)   { RT_UNUSED(lock); rt_hw_interrupt_enable(level);  }
+#define rt_spin_lock_init(lock)                                     do {RT_UNUSED(lock);} while (0)
+#define rt_spin_lock(lock)                                          do {RT_UNUSED(lock);} while (0)
+#define rt_spin_unlock(lock)                                        do {RT_UNUSED(lock);} while (0)
+rt_inline rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)  {RT_UNUSED(lock);return rt_hw_interrupt_disable();}
+#define rt_spin_unlock_irqrestore(lock, level)                      do {RT_UNUSED(lock); rt_hw_interrupt_enable(level);} while (0)
 #endif /* RT_USING_SMP */
 
 /**@}*/