[Cbe-oss-dev] [PATCH 4/10 v2] MARS: task barrier fix notify

Yuji Mano Yuji.Mano at am.sony.com
Sat Aug 30 05:22:29 EST 2008


This fixes a bug in task barrier's notify function so it only sends a signal to
workload id's that are in the wait list.

This also fixes a bug where the barrier count was not being properly reset once
the barrier is released.

Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>

---
v2:
 - fixed functionality of the barrier with the requirement that
   (total count == # of notify == # of wait calls)
 - reset barrier when all tasks have notified and waited
 - return error when # of notifies exceeds barrier total

 include/common/mars/mars_task_barrier_types.h |    5 +-
 src/host/lib/mars_task_barrier.c              |    3 +
 src/mpu/lib/mars_task_barrier.c               |   46 +++++++++++++++++++-------
 3 files changed, 40 insertions(+), 14 deletions(-)

--- a/include/common/mars/mars_task_barrier_types.h
+++ b/include/common/mars/mars_task_barrier_types.h
@@ -72,7 +72,7 @@ extern "C" {
  * \ingroup group_mars_task_barrier
  * \brief Maximum tasks allowed for single barrier
  */
-#define MARS_TASK_BARRIER_WAIT_MAX		53
+#define MARS_TASK_BARRIER_WAIT_MAX		51
 
 /**
  * \ingroup group_mars_task_barrier
@@ -88,7 +88,8 @@ extern "C" {
 struct mars_task_barrier {
 	uint32_t lock;
 	uint32_t total;
-	uint32_t count;
+	uint32_t notified_count;
+	uint32_t waited_count;
 	uint16_t wait_count;
 	uint16_t wait_id[MARS_TASK_BARRIER_WAIT_MAX];
 	uint64_t mars_context_ea;
--- a/src/host/lib/mars_task_barrier.c
+++ b/src/host/lib/mars_task_barrier.c
@@ -57,7 +57,8 @@ int mars_task_barrier_initialize(struct 
 
 	barrier->mars_context_ea = (uint64_t)(uintptr_t)mars;
 	barrier->total = total;
-	barrier->count = 0;
+	barrier->notified_count = 0;
+	barrier->waited_count = 0;
 	barrier->wait_count = 0;
 
 	mars_mutex_unlock((struct mars_mutex *)barrier);
--- a/src/mpu/lib/mars_task_barrier.c
+++ b/src/mpu/lib/mars_task_barrier.c
@@ -56,7 +56,8 @@ int mars_task_barrier_initialize(uint64_
 
 	barrier.mars_context_ea = mars_get_mars_context_ea();
 	barrier.total = total;
-	barrier.count = 0;
+	barrier.notified_count = 0;
+	barrier.waited_count = 0;
 	barrier.wait_count = 0;
 
 	mars_mutex_unlock_put(barrier_ea, (struct mars_mutex *)&barrier);
@@ -74,13 +75,19 @@ int mars_task_barrier_notify(uint64_t ba
 
 	mars_mutex_lock_get(barrier_ea, (struct mars_mutex *)&barrier);
 
-	/* set the necessary bits */
-	barrier.count++;
+	/* check if barrier notify limit reached */
+	MARS_CHECK_CLEANUP_RET(barrier.notified_count < barrier.total,
+		mars_mutex_unlock_put(barrier_ea,
+				(struct mars_mutex *)&barrier),
+		MARS_ERROR_LIMIT);
 
-	/* barrier count reached total so release barrier */
-	if (barrier.count == barrier.total) {
+	/* increment notified count */
+	barrier.notified_count++;
+
+	/* notified count reached total so release barrier */
+	if (barrier.notified_count == barrier.total) {
 		/* signal all task ids in wait list */
-		for (i = 0; i < barrier.total; i++)
+		for (i = 0; i < barrier.wait_count; i++)
 			mars_signal_send(barrier.wait_id[i]);
 
 		/* flush wait list */
@@ -109,16 +116,18 @@ int mars_task_barrier_wait(uint64_t barr
 	mars_mutex_lock_get(barrier_ea, (struct mars_mutex *)&barrier);
 
 	/* check if barrier wait limit reached */
-	MARS_CHECK_CLEANUP_RET(barrier.wait_count < MARS_TASK_BARRIER_WAIT_MAX,
+	MARS_CHECK_CLEANUP_RET(barrier.wait_count < barrier.total,
 		mars_mutex_unlock_put(barrier_ea,
 				(struct mars_mutex *)&barrier),
 		MARS_ERROR_LIMIT);
 
+	/* increment waited count */
+	barrier.waited_count++;
+
 	/* not all tasks notified barrier so need to wait */
-	if (barrier.count != barrier.total) {
+	if (barrier.notified_count != barrier.total) {
 		/* add id to wait list */
-		barrier.wait_id[barrier.wait_count] =
-			mars_get_workload_id();
+		barrier.wait_id[barrier.wait_count] = mars_get_workload_id();
 		barrier.wait_count++;
 
 		mars_mutex_unlock_put(barrier_ea,
@@ -130,6 +139,12 @@ int mars_task_barrier_wait(uint64_t barr
 		return MARS_SUCCESS;
 	}
 
+	/* all tasks have called wait so reset barrier */
+	if (barrier.waited_count == barrier.total) {
+		barrier.notified_count = 0;
+		barrier.waited_count = 0;
+	}
+
 	mars_mutex_unlock_put(barrier_ea, (struct mars_mutex *)&barrier);
 
 	return MARS_SUCCESS;
@@ -144,12 +159,21 @@ int mars_task_barrier_try_wait(uint64_t 
 	mars_mutex_lock_get(barrier_ea, (struct mars_mutex *)&barrier);
 
 	/* not all tasks notified barrier so return busy */
-	if (barrier.count != barrier.total) {
+	if (barrier.notified_count != barrier.total) {
 		mars_mutex_unlock_put(barrier_ea,
 				(struct mars_mutex *)&barrier);
 		return MARS_ERROR_BUSY;
 	}
 
+	/* increment waited count */
+	barrier.waited_count++;
+
+	/* all tasks have called wait so reset barrier */
+	if (barrier.waited_count == barrier.total) {
+		barrier.notified_count = 0;
+		barrier.waited_count = 0;
+	}
+
 	mars_mutex_unlock_put(barrier_ea, (struct mars_mutex *)&barrier);
 
 	return MARS_SUCCESS;





More information about the cbe-oss-dev mailing list