xiaoxiang781216 commented on code in PR #10605:
URL: https://github.com/apache/nuttx/pull/10605#discussion_r1328064849


##########
sched/semaphore/spinlock.c:
##########
@@ -384,4 +384,176 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned 
int cpu,
 }
 #endif
 
+/****************************************************************************
+ * Name: fair_spinlock_list_init
+ *
+ * Description:
+ *   Initialize the link linsk of fair spinlock.
+ *   If there is any spinlock node, the node will get lock.
+ *
+ * Input Parameters:
+ *   lock_list - A reference to the spinlock list.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   None.
+ *
+ ****************************************************************************/
+
+void fair_spinlock_list_init(fair_spinlock_list_t *lock_list)
+{
+  lock_list->lock = SP_UNLOCKED;
+  list_initialize(&lock_list->list);
+}
+
+/****************************************************************************
+ * Name: fair_spinlock_init
+ *
+ * Description:
+ *   Initialize the fair spinlock. Tje lock state is set as SP_LOCK util
+ *   some give lock to holder.
+ *
+ * Input Parameters:
+ *   lock - A reference to the spinlock object to lock.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Not running at the interrupt level.
+ *
+ ****************************************************************************/
+
+void fair_spinlock_init(fair_spinlock_t *lock)
+{
+  lock->lock = SP_LOCKED;
+  lock->holder = this_task();
+  list_initialize(&lock->node);
+}
+
+/****************************************************************************
+ * Name: fair_spin_lock
+ *
+ * Description:
+ *   Try to lock the spinlock and insert this lock to lock list.
+ *   If list is empty, the caller can get the lock.
+ *   If list is not empty, the lock will be inserted to this list.
+ *
+ * Input Parameters:
+ *   lock_list - A reference to fair lock list and insert this lock to list.
+ *   fair_lock - A reference to the spinlock object to lock.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Not running at the interrupt level.
+ *
+ ****************************************************************************/
+
+void fair_spin_lock(FAR fair_spinlock_list_t *lock_list,
+                    FAR fair_spinlock_t *fair_lock)
+{
+  FAR struct tcb_s *rtcb = this_task();
+  fair_spinlock_t *entry;
+  fair_spinlock_t *temp;
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  /* Notify that we have the spinlock */
+
+  sched_note_spinlock(this_task(), &fair_lock->lock, NOTE_SPINLOCK_LOCKED);
+#endif
+
+  /* There is no thread  wait this lock */
+
+  spin_lock(&lock_list->lock);
+
+  /* There is no node hold this lock */
+
+  if (list_is_empty(&lock_list->list))
+    {
+      fair_lock->lock = SP_UNLOCKED;

Review Comment:
   > There is a scenario. High priority thread get big number. Low priority one 
get small number So higher priority thread always try to get lock but low 
priority always sleeps. So higher can’t get the lock and always spin.
   > 
   > I think this scenario may happens. Sorry I don’t familiar scheduler but I 
guess that may happen.
   
   spinlock need hold together with irq/sched disable, otherwise the deadlock 
will happen frequently. For example, even with the current simple lock 
implementation:
   
   1. The low priority thread run on CPU0 hold the spin lock and do the state 
manipulation.
   2. Thread run on CPU1 may wake up a high thread and the scheduler decide to 
run it on CPU0
   3. The high priority thread run on CPU1 and try to hold the spin lock 
acquired by step 1
   
   And then the deadlock happen.



##########
sched/semaphore/spinlock.c:
##########
@@ -384,4 +384,176 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned 
int cpu,
 }
 #endif
 
+/****************************************************************************
+ * Name: fair_spinlock_list_init
+ *
+ * Description:
+ *   Initialize the link linsk of fair spinlock.
+ *   If there is any spinlock node, the node will get lock.
+ *
+ * Input Parameters:
+ *   lock_list - A reference to the spinlock list.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   None.
+ *
+ ****************************************************************************/
+
+void fair_spinlock_list_init(fair_spinlock_list_t *lock_list)
+{
+  lock_list->lock = SP_UNLOCKED;
+  list_initialize(&lock_list->list);
+}
+
+/****************************************************************************
+ * Name: fair_spinlock_init
+ *
+ * Description:
+ *   Initialize the fair spinlock. Tje lock state is set as SP_LOCK util
+ *   some give lock to holder.
+ *
+ * Input Parameters:
+ *   lock - A reference to the spinlock object to lock.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Not running at the interrupt level.
+ *
+ ****************************************************************************/
+
+void fair_spinlock_init(fair_spinlock_t *lock)
+{
+  lock->lock = SP_LOCKED;
+  lock->holder = this_task();
+  list_initialize(&lock->node);
+}
+
+/****************************************************************************
+ * Name: fair_spin_lock
+ *
+ * Description:
+ *   Try to lock the spinlock and insert this lock to lock list.
+ *   If list is empty, the caller can get the lock.
+ *   If list is not empty, the lock will be inserted to this list.
+ *
+ * Input Parameters:
+ *   lock_list - A reference to fair lock list and insert this lock to list.
+ *   fair_lock - A reference to the spinlock object to lock.
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Not running at the interrupt level.
+ *
+ ****************************************************************************/
+
+void fair_spin_lock(FAR fair_spinlock_list_t *lock_list,
+                    FAR fair_spinlock_t *fair_lock)
+{
+  FAR struct tcb_s *rtcb = this_task();
+  fair_spinlock_t *entry;
+  fair_spinlock_t *temp;
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS
+  /* Notify that we have the spinlock */
+
+  sched_note_spinlock(this_task(), &fair_lock->lock, NOTE_SPINLOCK_LOCKED);
+#endif
+
+  /* There is no thread  wait this lock */
+
+  spin_lock(&lock_list->lock);
+
+  /* There is no node hold this lock */
+
+  if (list_is_empty(&lock_list->list))
+    {
+      fair_lock->lock = SP_UNLOCKED;

Review Comment:
   > There is a scenario. High priority thread get big number. Low priority one 
get small number So higher priority thread always try to get lock but low 
priority always sleeps. So higher can’t get the lock and always spin.
   > 
   > I think this scenario may happens. Sorry I don’t familiar scheduler but I 
guess that may happen.
   
   spinlock need hold together with irq/sched disable, otherwise the deadlock 
will happen frequently. For example, even with the current simple lock 
implementation:
   
   1. The low priority thread run on CPU0 hold the spin lock and do the state 
manipulation.
   2. Thread run on CPU1 may wake up a high thread and the scheduler decide to 
run it on CPU0
   3. The high priority thread run on CPU1 and try to hold the spin lock 
acquired by step 1
   
   And then the deadlock happen.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to