forked from Imagelibrary/rtems
score: Fix resource count for self-contained mutex
This commit is contained in:
@@ -141,6 +141,7 @@ static void _Mutex_Release_slow(
|
|||||||
first = ( *operations->first )( heads );
|
first = ( *operations->first )( heads );
|
||||||
|
|
||||||
mutex->owner = first;
|
mutex->owner = first;
|
||||||
|
++first->resource_count;
|
||||||
unblock = _Thread_queue_Extract_locked(
|
unblock = _Thread_queue_Extract_locked(
|
||||||
&mutex->Queue.Queue,
|
&mutex->Queue.Queue,
|
||||||
operations,
|
operations,
|
||||||
@@ -214,10 +215,10 @@ void _Mutex_Acquire( struct _Mutex_Control *_mutex )
|
|||||||
executing = _Mutex_Queue_acquire( mutex, &lock_context );
|
executing = _Mutex_Queue_acquire( mutex, &lock_context );
|
||||||
|
|
||||||
owner = mutex->owner;
|
owner = mutex->owner;
|
||||||
++executing->resource_count;
|
|
||||||
|
|
||||||
if ( __predict_true( owner == NULL ) ) {
|
if ( __predict_true( owner == NULL ) ) {
|
||||||
mutex->owner = executing;
|
mutex->owner = executing;
|
||||||
|
++executing->resource_count;
|
||||||
_Mutex_Queue_release( mutex, &lock_context );
|
_Mutex_Queue_release( mutex, &lock_context );
|
||||||
} else {
|
} else {
|
||||||
_Mutex_Acquire_slow( mutex, owner, executing, 0, &lock_context );
|
_Mutex_Acquire_slow( mutex, owner, executing, 0, &lock_context );
|
||||||
@@ -238,10 +239,10 @@ int _Mutex_Acquire_timed(
|
|||||||
executing = _Mutex_Queue_acquire( mutex, &lock_context );
|
executing = _Mutex_Queue_acquire( mutex, &lock_context );
|
||||||
|
|
||||||
owner = mutex->owner;
|
owner = mutex->owner;
|
||||||
++executing->resource_count;
|
|
||||||
|
|
||||||
if ( __predict_true( owner == NULL ) ) {
|
if ( __predict_true( owner == NULL ) ) {
|
||||||
mutex->owner = executing;
|
mutex->owner = executing;
|
||||||
|
++executing->resource_count;
|
||||||
_Mutex_Queue_release( mutex, &lock_context );
|
_Mutex_Queue_release( mutex, &lock_context );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ typedef struct {
|
|||||||
rtems_id mid;
|
rtems_id mid;
|
||||||
rtems_id low;
|
rtems_id low;
|
||||||
struct _Mutex_Control mtx;
|
struct _Mutex_Control mtx;
|
||||||
|
struct _Mutex_Control deadlock_mtx;
|
||||||
struct _Mutex_recursive_Control rec_mtx;
|
struct _Mutex_recursive_Control rec_mtx;
|
||||||
struct _Condition_Control cond;
|
struct _Condition_Control cond;
|
||||||
struct _Semaphore_Control sem;
|
struct _Semaphore_Control sem;
|
||||||
@@ -491,6 +493,19 @@ static void mid_task(rtems_task_argument arg)
|
|||||||
rtems_test_assert(0);
|
rtems_test_assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void deadlock_cleanup(void *arg)
|
||||||
|
{
|
||||||
|
struct _Mutex_Control *deadlock_mtx = arg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The thread terminate procedure will dequeue us from the wait queue. So,
|
||||||
|
* one release is sufficient.
|
||||||
|
*/
|
||||||
|
|
||||||
|
_Mutex_Release(deadlock_mtx);
|
||||||
|
_Mutex_Destroy(deadlock_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
static void high_task(rtems_task_argument idx)
|
static void high_task(rtems_task_argument idx)
|
||||||
{
|
{
|
||||||
test_context *ctx = &test_instance;
|
test_context *ctx = &test_instance;
|
||||||
@@ -537,10 +552,15 @@ static void high_task(rtems_task_argument idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((events & EVENT_MTX_DEADLOCK) != 0) {
|
if ((events & EVENT_MTX_DEADLOCK) != 0) {
|
||||||
struct _Mutex_Control dead = _MUTEX_INITIALIZER;
|
struct _Mutex_Control *deadlock_mtx = &ctx->deadlock_mtx;
|
||||||
|
|
||||||
_Mutex_Acquire(&dead);
|
pthread_cleanup_push(deadlock_cleanup, deadlock_mtx);
|
||||||
_Mutex_Acquire(&dead);
|
|
||||||
|
_Mutex_Initialize(deadlock_mtx);
|
||||||
|
_Mutex_Acquire(deadlock_mtx);
|
||||||
|
_Mutex_Acquire(deadlock_mtx);
|
||||||
|
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((events & EVENT_REC_MTX_ACQUIRE) != 0) {
|
if ((events & EVENT_REC_MTX_ACQUIRE) != 0) {
|
||||||
@@ -653,6 +673,15 @@ static void test(void)
|
|||||||
|
|
||||||
send_event(ctx, 0, EVENT_MTX_DEADLOCK);
|
send_event(ctx, 0, EVENT_MTX_DEADLOCK);
|
||||||
|
|
||||||
|
sc = rtems_task_delete(ctx->mid);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_task_delete(ctx->high[0]);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
|
sc = rtems_task_delete(ctx->high[1]);
|
||||||
|
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
_Mutex_Destroy(&ctx->mtx);
|
_Mutex_Destroy(&ctx->mtx);
|
||||||
_Mutex_recursive_Destroy(&ctx->rec_mtx);
|
_Mutex_recursive_Destroy(&ctx->rec_mtx);
|
||||||
_Condition_Destroy(&ctx->cond);
|
_Condition_Destroy(&ctx->cond);
|
||||||
|
|||||||
Reference in New Issue
Block a user