This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit df183b668272dafb7e3e236fcbdf6d87ede6f3b9
Author: ouyangxiangzhen <ouyangxiangz...@xiaomi.com>
AuthorDate: Wed Jun 4 17:11:49 2025 +0800

    sched/wqueue: Remove the work_queue_period.
    
    For simplicity, better performance and lower memory-overhead, this commit 
replaced the periodical workqueue APIs with the more expressive 
work_queue_next. The work_queue_next restarts work based on the last expiration 
time.
    
    Signed-off-by: ouyangxiangzhen <ouyangxiangz...@xiaomi.com>
---
 include/nuttx/wqueue.h      |  25 +++-------
 sched/wqueue/kwork_queue.c  | 118 ++++++++++++++++++++++++++++----------------
 sched/wqueue/kwork_thread.c |  25 +---------
 3 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h
index 6eaefff597..f9b3470efe 100644
--- a/include/nuttx/wqueue.h
+++ b/include/nuttx/wqueue.h
@@ -251,7 +251,6 @@ struct work_s
 {
   struct list_node node;   /* Implements a double linked list */
   clock_t          qtime;  /* Time work queued */
-  clock_t          period; /* Periodical delay ticks */
   worker_t         worker; /* Work callback */
   FAR void        *arg;    /* Callback argument */
 };
@@ -411,18 +410,11 @@ int work_queue_wq(FAR struct kwork_wqueue_s *wqueue,
                   FAR void *arg, clock_t delay);
 
 /****************************************************************************
- * Name: work_queue_period/work_queue_period_wq
+ * Name: work_queue_next/work_queue_next_wq
  *
  * Description:
- *   Queue work to be performed periodically.  All queued work will be
- *   performed on the worker thread of execution (not the caller's).
- *
- *   The work structure is allocated and must be initialized to all zero by
- *   the caller.  Otherwise, the work structure is completely managed by the
- *   work queue logic.  The caller should never modify the contents of the
- *   work queue structure directly.  If work_queue() is called before the
- *   previous work has been performed and removed from the queue, then any
- *   pending work will be canceled and lost.
+ *   Queue work to be performed at a later time based on the last expiration
+ *   time. This function must be called in the workqueue callback.
  *
  * Input Parameters:
  *   qid    - The work queue ID (must be HPWORK or LPWORK)
@@ -434,18 +426,17 @@ int work_queue_wq(FAR struct kwork_wqueue_s *wqueue,
  *            it is invoked.
  *   delay  - Delay (in clock ticks) from the time queue until the worker
  *            is invoked. Zero means to perform the work immediately.
- *   period - Period (in clock ticks).
  *
  * Returned Value:
  *   Zero on success, a negated errno on failure
  *
  ****************************************************************************/
 
-int work_queue_period(int qid, FAR struct work_s *work, worker_t worker,
-                      FAR void *arg, clock_t delay, clock_t period);
-int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
-                         FAR struct work_s *work, worker_t worker,
-                         FAR void *arg, clock_t delay, clock_t period);
+int work_queue_next(int qid, FAR struct work_s *work, worker_t worker,
+                    FAR void *arg, clock_t delay);
+int work_queue_next_wq(FAR struct kwork_wqueue_s *wqueue,
+                       FAR struct work_s *work, worker_t worker,
+                       FAR void *arg, clock_t delay);
 
 /****************************************************************************
  * Name: work_queue_pri
diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c
index ede28bb65c..75b5a7f5fd 100644
--- a/sched/wqueue/kwork_queue.c
+++ b/sched/wqueue/kwork_queue.c
@@ -45,18 +45,11 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: work_queue_period/work_queue_period_wq
+ * Name: work_queue_next/work_queue_next_wq
  *
  * Description:
- *   Queue work to be performed periodically.  All queued work will be
- *   performed on the worker thread of execution (not the caller's).
- *
- *   The work structure is allocated and must be initialized to all zero by
- *   the caller.  Otherwise, the work structure is completely managed by the
- *   work queue logic.  The caller should never modify the contents of the
- *   work queue structure directly.  If work_queue() is called before the
- *   previous work has been performed and removed from the queue, then any
- *   pending work will be canceled and lost.
+ *   Queue work to be performed at a later time based on the last expiration
+ *   time. This function must be called in the workqueue callback.
  *
  * Input Parameters:
  *   qid    - The work queue ID (must be HPWORK or LPWORK)
@@ -68,20 +61,17 @@
  *            it is invoked.
  *   delay  - Delay (in clock ticks) from the time queue until the worker
  *            is invoked. Zero means to perform the work immediately.
- *   period - Period (in clock ticks).
  *
  * Returned Value:
  *   Zero on success, a negated errno on failure
  *
  ****************************************************************************/
 
-int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
-                         FAR struct work_s *work, worker_t worker,
-                         FAR void *arg, clock_t delay, clock_t period)
+int work_queue_next_wq(FAR struct kwork_wqueue_s *wqueue,
+                       FAR struct work_s *work, worker_t worker,
+                       FAR void *arg, clock_t delay)
 {
   irqstate_t flags;
-  clock_t expected;
-  bool retimer;
 
   if (wqueue == NULL || work == NULL || worker == NULL ||
       delay > WDOG_MAX_DELAY)
@@ -89,25 +79,14 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
       return -EINVAL;
     }
 
-  expected = clock_delay2abstick(delay);
+  /* Initialize the work structure. */
 
-  /* Interrupts are disabled so that this logic can be called from with
-   * task logic or from interrupt handling logic.
-   */
+  work->worker = worker; /* Work callback. non-NULL means queued */
+  work->arg    = arg;    /* Callback argument */
+  work->qtime += delay;  /* Expected time based on last expiration time */
 
   flags = spin_lock_irqsave(&wqueue->lock);
 
-  /* Ensure the work has been removed. */
-
-  retimer = work_available(work) ? false : work_remove(wqueue, work);
-
-  /* Initialize the work structure. */
-
-  work->worker = worker;   /* Work callback. non-NULL means queued */
-  work->arg    = arg;      /* Callback argument */
-  work->qtime  = expected; /* Expected time */
-  work->period = period;   /* Periodical delay */
-
   if (delay)
     {
       /* Insert to the pending list of the wqueue. */
@@ -116,7 +95,6 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
         {
           /* Start the timer if the work is the earliest expired work. */
 
-          retimer = false;
           wd_start_abstick(&wqueue->timer, work->qtime,
                            work_timer_expired, (wdparm_t)wqueue);
         }
@@ -128,11 +106,6 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
       list_add_tail(&wqueue->expired, &work->node);
     }
 
-  if (retimer)
-    {
-      work_timer_reset(wqueue);
-    }
-
   spin_unlock_irqrestore(&wqueue->lock, flags);
 
   if (!delay)
@@ -145,11 +118,10 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s 
*wqueue,
   return 0;
 }
 
-int work_queue_period(int qid, FAR struct work_s *work, worker_t worker,
-                      FAR void *arg, clock_t delay, clock_t period)
+int work_queue_next(int qid, FAR struct work_s *work, worker_t worker,
+                    FAR void *arg, clock_t delay)
 {
-  return work_queue_period_wq(work_qid2wq(qid), work, worker,
-                              arg, delay, period);
+  return work_queue_next_wq(work_qid2wq(qid), work, worker, arg, delay);
 }
 
 /****************************************************************************
@@ -186,7 +158,69 @@ int work_queue_wq(FAR struct kwork_wqueue_s *wqueue,
                   FAR struct work_s *work, worker_t worker,
                   FAR void *arg, clock_t delay)
 {
-  return work_queue_period_wq(wqueue, work, worker, arg, delay, 0);
+  irqstate_t flags;
+  clock_t expected;
+  bool retimer;
+
+  if (wqueue == NULL || work == NULL || worker == NULL ||
+      delay > WDOG_MAX_DELAY)
+    {
+      return -EINVAL;
+    }
+
+  expected = clock_delay2abstick(delay);
+
+  /* Interrupts are disabled so that this logic can be called from with
+   * task logic or from interrupt handling logic.
+   */
+
+  flags = spin_lock_irqsave(&wqueue->lock);
+
+  /* Ensure the work has been removed. */
+
+  retimer = work_available(work) ? false : work_remove(wqueue, work);
+
+  /* Initialize the work structure. */
+
+  work->worker = worker;   /* Work callback. non-NULL means queued */
+  work->arg    = arg;      /* Callback argument */
+  work->qtime  = expected; /* Expected time */
+
+  if (delay)
+    {
+      /* Insert to the pending list of the wqueue. */
+
+      if (work_insert_pending(wqueue, work))
+        {
+          /* Start the timer if the work is the earliest expired work. */
+
+          retimer = false;
+          wd_start_abstick(&wqueue->timer, work->qtime,
+                           work_timer_expired, (wdparm_t)wqueue);
+        }
+    }
+  else
+    {
+      /* Insert to the expired list of the wqueue. */
+
+      list_add_tail(&wqueue->expired, &work->node);
+    }
+
+  if (retimer)
+    {
+      work_timer_reset(wqueue);
+    }
+
+  spin_unlock_irqrestore(&wqueue->lock, flags);
+
+  if (!delay)
+    {
+      /* Immediately wake up the worker thread. */
+
+      nxsem_post(&wqueue->sem);
+    }
+
+  return 0;
 }
 
 int work_queue(int qid, FAR struct work_s *work, worker_t worker,
diff --git a/sched/wqueue/kwork_thread.c b/sched/wqueue/kwork_thread.c
index be1a77185e..a46c050528 100644
--- a/sched/wqueue/kwork_thread.c
+++ b/sched/wqueue/kwork_thread.c
@@ -239,30 +239,9 @@ static int work_thread(int argc, FAR char *argv[])
 
           arg = work->arg;
 
-          /* Check whether the work is periodic. */
+          /* Return the work structure ownership to the work owner. */
 
-          if (work->period != 0)
-            {
-              /* Calculate next expiration qtime. */
-
-              work->qtime += work->period;
-
-              /* Enqueue to the waiting queue */
-
-              if (work_insert_pending(wqueue, work))
-                {
-                  /* We should reset timer if the work is the earliest. */
-
-                  wd_start_abstick(&wqueue->timer, work->qtime,
-                                   work_timer_expired, (wdparm_t)wqueue);
-                }
-            }
-          else
-            {
-              /* Return the work structure ownership to the work owner. */
-
-              work->worker = NULL;
-            }
+          work->worker = NULL;
 
           /* Mark the thread busy */
 

Reply via email to