mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-24 11:12:27 +08:00
score: Modify _Per_CPU_Perform_jobs()
Process only the jobs initially registered on the processing list. This makes it possible to add jobs for the current processor in a job handler. These jobs are processed with the next SMP_MESSAGE_PERFORM_JOBS message. The lock is only acquired and released once.
This commit is contained in:
@@ -44,18 +44,20 @@ void _Per_CPU_Perform_jobs( Per_CPU_Control *cpu )
|
||||
Per_CPU_Job *job;
|
||||
|
||||
_Per_CPU_Jobs_ISR_disable_and_acquire( cpu, &lock_context );
|
||||
job = cpu->Jobs.head;
|
||||
cpu->Jobs.head = NULL;
|
||||
_Per_CPU_Jobs_release_and_ISR_enable( cpu, &lock_context );
|
||||
|
||||
while ( ( job = cpu->Jobs.head ) != NULL ) {
|
||||
while ( job != NULL ) {
|
||||
const Per_CPU_Job_context *context;
|
||||
|
||||
cpu->Jobs.head = job->next;
|
||||
_Per_CPU_Jobs_release_and_ISR_enable( cpu, &lock_context );
|
||||
Per_CPU_Job *next;
|
||||
|
||||
context = job->context;
|
||||
next = job->next;
|
||||
( *context->handler )( context->arg );
|
||||
_Atomic_Store_ulong( &job->done, PER_CPU_JOB_DONE, ATOMIC_ORDER_RELEASE );
|
||||
|
||||
_Per_CPU_Jobs_ISR_disable_and_acquire( cpu, &lock_context );
|
||||
job = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -394,6 +394,47 @@ T_TEST_CASE(JobOrder)
|
||||
_Thread_Dispatch_enable(cpu_self);
|
||||
}
|
||||
|
||||
#define TEST_ADD_JOB_IN_JOB_JOBS 3
|
||||
|
||||
static Per_CPU_Job add_job_in_job_jobs[TEST_ADD_JOB_IN_JOB_JOBS];
|
||||
|
||||
static void add_job_in_job_handler_0(void *arg)
|
||||
{
|
||||
T_step(1, "invalid job order");
|
||||
_Per_CPU_Add_job(_Per_CPU_Get(), &add_job_in_job_jobs[1]);
|
||||
}
|
||||
|
||||
static void add_job_in_job_handler_1(void *arg)
|
||||
{
|
||||
T_step(3, "invalid job order");
|
||||
}
|
||||
|
||||
static const Per_CPU_Job_context
|
||||
add_job_in_job_contexts[TEST_ADD_JOB_IN_JOB_JOBS] = {
|
||||
{ .handler = add_job_in_job_handler_0 },
|
||||
{ .handler = add_job_in_job_handler_1 }
|
||||
};
|
||||
|
||||
T_TEST_CASE(AddJobInJob)
|
||||
{
|
||||
Per_CPU_Control *cpu_self;
|
||||
size_t i;
|
||||
|
||||
T_plan(4);
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
|
||||
for (i = 0; i < TEST_ADD_JOB_IN_JOB_JOBS; ++i) {
|
||||
add_job_in_job_jobs[i].context = &add_job_in_job_contexts[i];
|
||||
}
|
||||
|
||||
_Per_CPU_Add_job(cpu_self, &add_job_in_job_jobs[0]);
|
||||
T_step(0, "wrong job processing time");
|
||||
_SMP_Send_message(_Per_CPU_Get_index(cpu_self), SMP_MESSAGE_PERFORM_JOBS);
|
||||
T_step(2, "wrong job processing time");
|
||||
_SMP_Send_message(_Per_CPU_Get_index(cpu_self), SMP_MESSAGE_PERFORM_JOBS);
|
||||
_Thread_Dispatch_enable(cpu_self);
|
||||
}
|
||||
|
||||
T_TEST_CASE(UnicastDuringMultitaskingIRQDisabled)
|
||||
{
|
||||
test_unicast(&test_instance, multicast_action_irq_disabled);
|
||||
|
||||
Reference in New Issue
Block a user