[Sound-open-firmware] [PATCH] work: Add new work API calls for rescheduling work

Liam Girdwood liam.r.girdwood at linux.intel.com
Wed Sep 20 15:58:10 CEST 2017


Add support for rescheduling work with a new deadline and for scheduling
on a specific clock tick value.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/include/reef/work.h |  3 ++
 src/lib/work.c          | 74 ++++++++++++++++++++++++++++++-------------------
 2 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/src/include/reef/work.h b/src/include/reef/work.h
index 199e46c..516f98f 100644
--- a/src/include/reef/work.h
+++ b/src/include/reef/work.h
@@ -70,10 +70,13 @@ struct work_queue_timesource {
 
 /* schedule/cancel work on work queue */
 void work_schedule(struct work_queue *queue, struct work *w, uint64_t timeout);
+void work_reschedule(struct work_queue *queue, struct work *w, uint64_t timeout);
 void work_cancel(struct work_queue *queue, struct work *work);
 
 /* schedule/cancel work on default system work queue */
 void work_schedule_default(struct work *work, uint64_t timeout);
+void work_reschedule_default(struct work *work, uint64_t timeout);
+void work_reschedule_default_at(struct work *w, uint64_t time);
 void work_cancel_default(struct work *work);
 
 /* create new work queue */
diff --git a/src/lib/work.c b/src/lib/work.c
index cac3deb..c53f029 100644
--- a/src/lib/work.c
+++ b/src/lib/work.c
@@ -351,64 +351,82 @@ out:
 	spin_unlock_irq(&queue->lock, flags);
 }
 
-void work_cancel(struct work_queue *queue, struct work *w)
+void work_schedule_default(struct work *w, uint64_t timeout)
+{
+	work_schedule(queue_, w, timeout);
+}
+
+static void reschedule(struct work_queue *queue, struct work *w, uint64_t time)
 {
+	struct work *work;
+	struct list_item *wlist;
 	uint32_t flags;
 
 	spin_lock_irq(&queue->lock, flags);
 
-	/* remove work from list */
-	list_item_del(&w->list);
+	/* check to see if we are already scheduled ? */
+	list_for_item(wlist, &queue->work) {
+		work = container_of(wlist, struct work, list);
 
+		/* found it */
+		if (work == w)
+			goto found;
+	}
+
+	/* not found insert work into list */
+	list_item_prepend(&w->list, &queue->work);
+
+found:
 	/* re-calc timer and re-arm */
+	w->timeout = time;
 	queue_reschedule(queue);
 
 	spin_unlock_irq(&queue->lock, flags);
 }
 
-void work_schedule_default(struct work *w, uint64_t timeout)
+void work_reschedule(struct work_queue *queue, struct work *w, uint64_t timeout)
 {
-	struct work *work;
-	struct list_item *wlist;
-	uint32_t flags;
+	uint64_t time;
 
-	spin_lock_irq(&queue_->lock, flags);
-
-	/* check to see if we are already scheduled ? */
-	list_for_item(wlist, &queue_->work) {
-		work = container_of(wlist, struct work, list);
+	/* convert timeout micro seconds to CPU clock ticks */
+	time = queue->ticks_per_usec * timeout + work_get_timer(queue);
 
-		/* keep original timeout */
-		if (work == w)
-			goto out;
-	}
+	reschedule(queue, w, time);
+}
 
-	/* convert timeout microsecs to CPU clock ticks */
-	w->timeout = queue_->ticks_per_usec * timeout + work_get_timer(queue_);
+void work_reschedule_default(struct work *w, uint64_t timeout)
+{
+	uint64_t time;
 
-	/* insert work into list */
-	list_item_prepend(&w->list, &queue_->work);
+	/* convert timeout micro seconds to CPU clock ticks */
+	time = queue_->ticks_per_usec * timeout + work_get_timer(queue_);
 
-	/* re-calc timer and re-arm */
-	queue_reschedule(queue_);
+	reschedule(queue_, w, time);
+}
 
-out:
-	spin_unlock_irq(&queue_->lock, flags);
+void work_reschedule_default_at(struct work *w, uint64_t time)
+{
+	reschedule(queue_, w, time);
 }
 
-void work_cancel_default(struct work *w)
+void work_cancel(struct work_queue *queue, struct work *w)
 {
 	uint32_t flags;
 
-	spin_lock_irq(&queue_->lock, flags);
+	spin_lock_irq(&queue->lock, flags);
 
 	/* remove work from list */
 	list_item_del(&w->list);
 
 	/* re-calc timer and re-arm */
-	queue_reschedule(queue_);
+	queue_reschedule(queue);
 
-	spin_unlock_irq(&queue_->lock, flags);
+	spin_unlock_irq(&queue->lock, flags);
+}
+
+void work_cancel_default(struct work *w)
+{
+	work_cancel(queue_, w);
 }
 
 struct work_queue *work_new_queue(struct work_queue_timesource *ts)
-- 
2.11.0



More information about the Sound-open-firmware mailing list