forked from Imagelibrary/rtems
score: Add _Per_CPU_Wait_for_job()
This commit is contained in:
@@ -811,6 +811,20 @@ void _Per_CPU_Perform_jobs( Per_CPU_Control *cpu );
|
|||||||
*/
|
*/
|
||||||
void _Per_CPU_Add_job( Per_CPU_Control *cpu, Per_CPU_Job *job );
|
void _Per_CPU_Add_job( Per_CPU_Control *cpu, Per_CPU_Job *job );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waits for the job carried out by the specified processor.
|
||||||
|
*
|
||||||
|
* This function may result in an SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS
|
||||||
|
* fatal error.
|
||||||
|
*
|
||||||
|
* @param[in] cpu The processor carrying out the job.
|
||||||
|
* @param[in] job The job to wait for.
|
||||||
|
*/
|
||||||
|
void _Per_CPU_Wait_for_job(
|
||||||
|
const Per_CPU_Control *cpu,
|
||||||
|
const Per_CPU_Job *job
|
||||||
|
);
|
||||||
|
|
||||||
#endif /* defined( RTEMS_SMP ) */
|
#endif /* defined( RTEMS_SMP ) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -102,6 +102,36 @@ static void _Per_CPU_Try_perform_jobs( Per_CPU_Control *cpu_self )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _Per_CPU_Wait_for_job(
|
||||||
|
const Per_CPU_Control *cpu,
|
||||||
|
const Per_CPU_Job *job
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (
|
||||||
|
_Atomic_Load_ulong( &job->done, ATOMIC_ORDER_ACQUIRE )
|
||||||
|
!= PER_CPU_JOB_DONE
|
||||||
|
) {
|
||||||
|
switch ( cpu->state ) {
|
||||||
|
case PER_CPU_STATE_INITIAL:
|
||||||
|
case PER_CPU_STATE_READY_TO_START_MULTITASKING:
|
||||||
|
case PER_CPU_STATE_REQUEST_START_MULTITASKING:
|
||||||
|
_CPU_SMP_Processor_event_broadcast();
|
||||||
|
/* Fall through */
|
||||||
|
case PER_CPU_STATE_UP:
|
||||||
|
/*
|
||||||
|
* Calling this function with the current processor is intentional.
|
||||||
|
* We have to perform our own jobs here in case inter-processor
|
||||||
|
* interrupts are not working.
|
||||||
|
*/
|
||||||
|
_Per_CPU_Try_perform_jobs( _Per_CPU_Get() );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_SMP_Fatal( SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Per_CPU_Job_context Context;
|
Per_CPU_Job_context Context;
|
||||||
Per_CPU_Job Jobs[ CPU_MAXIMUM_PROCESSORS ];
|
Per_CPU_Job Jobs[ CPU_MAXIMUM_PROCESSORS ];
|
||||||
@@ -140,35 +170,12 @@ static void _SMP_Wait_for_action_jobs(
|
|||||||
|
|
||||||
for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
|
for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
|
||||||
if ( _Processor_mask_Is_set( targets, cpu_index ) ) {
|
if ( _Processor_mask_Is_set( targets, cpu_index ) ) {
|
||||||
const Per_CPU_Job *job;
|
const Per_CPU_Control *cpu;
|
||||||
Per_CPU_Control *cpu;
|
const Per_CPU_Job *job;
|
||||||
|
|
||||||
job = &jobs->Jobs[ cpu_index ];
|
|
||||||
cpu = _Per_CPU_Get_by_index( cpu_index );
|
cpu = _Per_CPU_Get_by_index( cpu_index );
|
||||||
|
job = &jobs->Jobs[ cpu_index ];
|
||||||
while (
|
_Per_CPU_Wait_for_job( cpu, job );
|
||||||
_Atomic_Load_ulong( &job->done, ATOMIC_ORDER_ACQUIRE )
|
|
||||||
!= PER_CPU_JOB_DONE
|
|
||||||
) {
|
|
||||||
switch ( cpu->state ) {
|
|
||||||
case PER_CPU_STATE_INITIAL:
|
|
||||||
case PER_CPU_STATE_READY_TO_START_MULTITASKING:
|
|
||||||
case PER_CPU_STATE_REQUEST_START_MULTITASKING:
|
|
||||||
_CPU_SMP_Processor_event_broadcast();
|
|
||||||
/* Fall through */
|
|
||||||
case PER_CPU_STATE_UP:
|
|
||||||
/*
|
|
||||||
* Calling this function with the current processor is intentional.
|
|
||||||
* We have to perform our own jobs here in case inter-processor
|
|
||||||
* interrupts are not working.
|
|
||||||
*/
|
|
||||||
_Per_CPU_Try_perform_jobs( _Per_CPU_Get() );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_SMP_Fatal( SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user