in testing/ostest/prioinherit.c [489:754]
void priority_inheritance(void)
{
#if defined(CONFIG_PRIORITY_INHERITANCE) && !defined(CONFIG_DISABLE_PTHREAD)
pthread_t lowpri[NLOWPRI_THREADS];
pthread_t medpri;
pthread_t highpri[NHIGHPRI_THREADS];
pthread_addr_t result;
pthread_attr_t attr;
struct sched_param sparam;
int my_pri;
int status;
int i;
pid_t pids[NUMBER_OF_COMPETING_THREADS];
char args[3][32];
FAR char *argv[4];
char name[32];
int priority;
int restoration_result;
printf("priority_inheritance: Started\n");
g_middlestate = NOTSTARTED;
for (i = 0; i < NHIGHPRI_THREADS; i++) g_highstate[i] = NOTSTARTED;
for (i = 0; i < NLOWPRI_THREADS; i++) g_lowstate[i] = NOTSTARTED;
status = sched_getparam(gettid(), &sparam);
if (status != 0)
{
printf("priority_inheritance: ERROR sched_getparam failed\n");
ASSERT(false);
sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY;
}
my_pri = sparam.sched_priority;
g_highpri = sched_get_priority_max(SCHED_FIFO);
g_lowpri = sched_get_priority_min(SCHED_FIFO);
g_medpri = my_pri - 1;
sem_init(&g_sem, 0, NLOWPRI_THREADS);
sem_setprotocol(&g_sem, SEM_PRIO_INHERIT);
dump_nfreeholders("priority_inheritance:");
/* Start the low priority threads */
for (i = 0; i < NLOWPRI_THREADS; i++)
{
int threadno = i + 1;
printf("priority_inheritance: "
"Starting lowpri_thread-%d (of %d) at %d\n",
threadno, NLOWPRI_THREADS, g_lowpri);
status = pthread_attr_init(&attr);
if (status != 0)
{
printf("priority_inheritance: "
"ERROR pthread_attr_init failed, status=%d\n",
status);
ASSERT(false);
}
sparam.sched_priority = g_lowpri;
status = pthread_attr_setschedparam(&attr, &sparam);
if (status != OK)
{
printf("priority_inheritance: "
"ERROR pthread_attr_setschedparam failed, status=%d\n",
status);
ASSERT(false);
}
else
{
printf("priority_inheritance: "
"Set lowpri_thread-%d priority to %d\n",
threadno, sparam.sched_priority);
}
status = pthread_create(&lowpri[i], &attr, lowpri_thread,
(FAR void *)((uintptr_t)threadno));
if (status != 0)
{
printf("priority_inheritance: "
"ERROR pthread_create failed, status=%d\n", status);
ASSERT(false);
}
}
printf("priority_inheritance: Waiting...\n");
sleep(2);
dump_nfreeholders("priority_inheritance:");
/* Start the medium priority thread */
printf("priority_inheritance: Starting medpri_thread at %d\n", g_medpri);
status = pthread_attr_init(&attr);
if (status != 0)
{
printf("priority_inheritance: "
"ERROR pthread_attr_init failed, status=%d\n", status);
ASSERT(false);
}
sparam.sched_priority = g_medpri;
status = pthread_attr_setschedparam(&attr, &sparam);
if (status != OK)
{
printf("priority_inheritance: "
"ERROR pthread_attr_setschedparam failed, status=%d\n",
status);
ASSERT(false);
}
else
{
printf("priority_inheritance: Set medpri_thread priority to %d\n",
sparam.sched_priority);
}
FFLUSH();
status = pthread_create(&medpri, &attr, medpri_thread, NULL);
if (status != 0)
{
printf("priority_inheritance: "
"ERROR pthread_create failed, status=%d\n",
status);
ASSERT(false);
}
printf("priority_inheritance: Waiting...\n");
sleep(1);
dump_nfreeholders("priority_inheritance:");
/* Start the high priority threads */
for (i = 0; i < NHIGHPRI_THREADS; i++)
{
int threadno = i + 1;
printf("priority_inheritance: "
"Starting highpri_thread-%d (of %d) at %d\n",
threadno, NHIGHPRI_THREADS, g_highpri);
status = pthread_attr_init(&attr);
if (status != 0)
{
printf("priority_inheritance: "
"ERROR pthread_attr_init failed, status=%d\n", status);
ASSERT(false);
}
sparam.sched_priority = g_highpri - i;
status = pthread_attr_setschedparam(&attr, &sparam);
if (status != OK)
{
printf("priority_inheritance: "
"ERROR pthread_attr_setschedparam failed, status=%d\n",
status);
ASSERT(false);
}
else
{
printf("priority_inheritance: "
"Set highpri_thread-%d priority to %d\n",
threadno, sparam.sched_priority);
}
FFLUSH();
status = pthread_create(&highpri[i], &attr, highpri_thread,
(FAR void *)((uintptr_t)threadno));
if (status != 0)
{
printf("priority_inheritance: "
"ERRROR pthread_create failed, status=%d\n", status);
ASSERT(false);
}
}
dump_nfreeholders("priority_inheritance:");
FFLUSH();
/* Wait for all thread instances to complete */
for (i = 0; i < NHIGHPRI_THREADS; i++)
{
printf("priority_inheritance: "
"Waiting for highpri_thread-%d to complete\n", i + 1);
FFLUSH();
pthread_join(highpri[i], &result);
dump_nfreeholders("priority_inheritance:");
}
printf("priority_inheritance: Waiting for medpri_thread to complete\n");
FFLUSH();
pthread_join(medpri, &result);
dump_nfreeholders("priority_inheritance:");
for (i = 0; i < NLOWPRI_THREADS; i++)
{
printf("priority_inheritance: "
"Waiting for lowpri_thread-%d to complete\n", i + 1);
FFLUSH();
pthread_join(lowpri[i], &result);
dump_nfreeholders("priority_inheritance:");
}
/* Perform restoration test */
printf("priority_inheritance: Restoration Test:\n");
sem_init(&g_sem, 0, 1);
priority = COMPETING_THREAD_START_PRIORITY;
argv[0] = args[0];
argv[1] = args[1];
argv[2] = args[2];
argv[3] = NULL;
for (i = 0; i < NUMBER_OF_COMPETING_THREADS; i++)
{
g_priority_tracking[i] = 0;
snprintf(name, sizeof(name), "Task%1d", i);
snprintf(args[0], sizeof(args[0]), "%d", i);
snprintf(args[1], sizeof(args[1]), "%d", i * 10000);
snprintf(args[2], sizeof(args[2]), "%d", i == 0 ? 100000 : 1000);
pids[i] = task_create(name, priority, CONFIG_DEFAULT_TASK_STACKSIZE,
adversary, argv);
priority += PRIORIY_SPREED;
}
priority = COMPETING_THREAD_START_PRIORITY;
restoration_result = 0;
for (i = 0; i < NUMBER_OF_COMPETING_THREADS; i++)
{
printf("priority_inheritance: "
"Waiting for Task-%d to complete\n", i);
waitpid(pids[i], &status, 0);
if (priority != g_priority_tracking[i])
{
printf("priority_inheritance: "
"Task-%d Priority is %d, and was not restored to %d\n",
i, g_priority_tracking[i], priority);
restoration_result |= 1 << i;
}
priority += PRIORIY_SPREED;
}
if (restoration_result != 0)
{
printf("priority_inheritance: ERROR: FAIL Priorities were not "
"correctly restored.\n");
ASSERT(false);
}
else
{
printf("priority_inheritance: PASSED Priority were correctly"
" restored.\n");
}
printf("priority_inheritance: Finished\n");
sem_destroy(&g_sem);
dump_nfreeholders("priority_inheritance:");
FFLUSH();
#endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_PTHREAD */
}