summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/score/src/threadqenqueue.c2
-rw-r--r--cpukit/score/src/threadqflush.c7
-rw-r--r--testsuites/smptests/smpmutex01/init.c58
3 files changed, 64 insertions, 3 deletions
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 62d3671222..f62ec29b02 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -568,7 +568,6 @@ bool _Thread_queue_Extract_locked(
Thread_queue_Context *queue_context
)
{
- _Thread_queue_Context_clear_priority_updates( queue_context );
#if defined(RTEMS_MULTIPROCESSING)
_Thread_queue_MP_set_callout( the_thread, queue_context );
#endif
@@ -627,6 +626,7 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
Thread_queue_Queue *queue;
_Thread_queue_Context_initialize( &queue_context );
+ _Thread_queue_Context_clear_priority_updates( &queue_context );
_Thread_Wait_acquire( the_thread, &queue_context );
queue = the_thread->Wait.queue;
diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c
index ef4d6b1f09..4310e06edf 100644
--- a/cpukit/score/src/threadqflush.c
+++ b/cpukit/score/src/threadqflush.c
@@ -92,6 +92,13 @@ size_t _Thread_queue_Flush_critical(
break;
}
+ /*
+ * We do not have enough space in the queue context to collect all priority
+ * updates, so clear it each time. We unconditionally do the priority
+ * update for the owner later if it exists.
+ */
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+
do_unblock = _Thread_queue_Extract_locked(
queue,
operations,
diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c
index 6586788876..3cf068d809 100644
--- a/testsuites/smptests/smpmutex01/init.c
+++ b/testsuites/smptests/smpmutex01/init.c
@@ -47,7 +47,9 @@ typedef enum {
REQ_SET_DONE = RTEMS_EVENT_10,
REQ_WAIT_FOR_DONE = RTEMS_EVENT_11,
REQ_SEND_EVENT_2 = RTEMS_EVENT_12,
- REQ_SEND_EVENT_3 = RTEMS_EVENT_13
+ REQ_SEND_EVENT_3 = RTEMS_EVENT_13,
+ REQ_CEIL_OBTAIN = RTEMS_EVENT_14,
+ REQ_CEIL_RELEASE = RTEMS_EVENT_15
} request_id;
typedef enum {
@@ -67,6 +69,7 @@ typedef struct {
rtems_id mtx;
rtems_id mtx_2;
rtems_id sem;
+ rtems_id ceil;
rtems_id tasks[TASK_COUNT];
Atomic_Uint done;
task_id id_2;
@@ -305,6 +308,22 @@ static void sem_release(test_context *ctx)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
+static void ceil_obtain(test_context *ctx)
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain(ctx->ceil, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void ceil_release(test_context *ctx)
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release(ctx->ceil);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
static void wait(void)
{
rtems_status_code sc;
@@ -467,6 +486,16 @@ static void worker(rtems_task_argument arg)
send_event(ctx, ctx->id_3, ctx->events_3);
}
+ if ((events & REQ_CEIL_OBTAIN) != 0) {
+ ceil_obtain(ctx);
+ ++ctx->generation[id];
+ }
+
+ if ((events & REQ_CEIL_RELEASE) != 0) {
+ ceil_release(ctx);
+ ++ctx->generation[id];
+ }
+
if ((events & REQ_SET_DONE) != 0) {
set_done(ctx);
}
@@ -520,6 +549,15 @@ static void test_init(test_context *ctx)
&ctx->sem
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('C', 'E', 'I', 'L'),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING,
+ 1,
+ &ctx->ceil
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static void test_simple_inheritance(test_context *ctx)
@@ -548,6 +586,21 @@ static void test_flush_inheritance(test_context *ctx)
release(ctx);
}
+static void test_ceiling_mutex(test_context *ctx)
+{
+ assert_prio(ctx, M, 3);
+ ceil_obtain(ctx);
+ assert_prio(ctx, M, 1);
+ send_event(ctx, A_1, REQ_CEIL_OBTAIN);
+ yield();
+ check_generations(ctx, NONE, NONE);
+ ceil_release(ctx);
+ check_generations(ctx, A_1, NONE);
+ assert_prio(ctx, M, 3);
+ send_event(ctx, A_1, REQ_CEIL_RELEASE);
+ check_generations(ctx, A_1, NONE);
+}
+
static void test_dequeue_order_one_scheduler_instance(test_context *ctx)
{
obtain(ctx);
@@ -967,6 +1020,7 @@ static void test(test_context *ctx)
}
test_flush_inheritance(ctx);
+ test_ceiling_mutex(ctx);
}
static void Init(rtems_task_argument arg)
@@ -1000,7 +1054,7 @@ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
#define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
-#define CONFIGURE_MAXIMUM_SEMAPHORES 3
+#define CONFIGURE_MAXIMUM_SEMAPHORES 4
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION