[Cbe-oss-dev] [PATCH 02/23]MARS/base: avoid host mutex contention
Yuji Mano
yuji.mano at am.sony.com
Sat Mar 14 12:18:07 EST 2009
From: Kazunori Asayama <asayama at sm.sony.co.jp>
Avoid host mutex contention
This patch avoids mutex contention on host side by using waiting
queue.
Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
---
base/src/host/lib/mutex_cell.c | 51 ++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 16 deletions(-)
Index: b/base/src/host/lib/mutex_cell.c
===================================================================
--- a/base/src/host/lib/mutex_cell.c 2009-02-19 22:40:34.000000000 +0900
+++ b/base/src/host/lib/mutex_cell.c 2009-02-20 12:02:13.000000000 +0900
@@ -36,6 +36,7 @@
*/
#include <ppu_intrinsics.h>
+#include <unistd.h>
#include "config.h"
@@ -43,6 +44,11 @@
#include "mars/error.h"
#include "mars/mutex.h"
+union mars_mutex_header {
+ struct mars_mutex_status status;
+ uint32_t bits;
+};
+
static void init_status(struct mars_mutex_status *status)
{
status->lock = MARS_MUTEX_UNLOCKED;
@@ -99,21 +105,37 @@ int mars_mutex_reset(uint64_t mutex_ea)
int mars_mutex_lock(uint64_t mutex_ea)
{
struct mars_mutex *mutex = mars_ea_to_ptr(mutex_ea);
- struct mars_mutex_status status;
- uint32_t value;
+ union mars_mutex_header header;
+ uint8_t id;
+ int retry;
if (!mutex_ea) {
return MARS_ERROR_NULL;
}
do {
- do {
- value = __lwarx(&mutex->status);
- status = *(struct mars_mutex_status *)&value;
- } while (status.lock == MARS_MUTEX_LOCKED);
- status.lock = MARS_MUTEX_LOCKED;
- value = *(uint32_t *)&status;
- } while (!__stwcx(&mutex->status, value));
+ header.bits = __lwarx(&mutex->status);
+
+ /* get my id */
+ id = header.status.next_id++;
+ } while (!__stwcx(&mutex->status, header.bits));
+
+ do {
+ header.bits = __lwarx(&mutex->status);
+
+ if (header.status.lock == MARS_MUTEX_LOCKED ||
+ header.status.current_id != id) {
+ /* wait until mutex is released */
+ usleep(1);
+ retry = 1;
+ }
+ else {
+ /* get lock */
+ header.status.lock = MARS_MUTEX_LOCKED;
+ header.status.current_id++;
+ retry = !__stwcx(&mutex->status, header.bits);
+ }
+ } while (retry);
__isync();
@@ -123,8 +145,7 @@ int mars_mutex_lock(uint64_t mutex_ea)
int mars_mutex_unlock(uint64_t mutex_ea)
{
struct mars_mutex *mutex = mars_ea_to_ptr(mutex_ea);
- struct mars_mutex_status status;
- uint32_t value;
+ union mars_mutex_header header;
if (!mutex_ea)
return MARS_ERROR_NULL;
@@ -134,11 +155,9 @@ int mars_mutex_unlock(uint64_t mutex_ea)
__lwsync();
do {
- value = __lwarx(&mutex->status);
- status = *(struct mars_mutex_status *)&value;
- status.lock = MARS_MUTEX_UNLOCKED;
- value = *(uint32_t *)&status;
- } while (!__stwcx(&mutex->status, value));
+ header.bits = __lwarx(&mutex->status);
+ header.status.lock = MARS_MUTEX_UNLOCKED;
+ } while (!__stwcx(&mutex->status, header.bits));
return MARS_SUCCESS;
}
More information about the cbe-oss-dev
mailing list