10dc076565f772bb1953209fb69ea150b494aaa40robbiew/* 20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2004, QUALCOMM Inc. All rights reserved. 30dc076565f772bb1953209fb69ea150b494aaa40robbiew * Created by: abisain REMOVE-THIS AT qualcomm DOT com 40dc076565f772bb1953209fb69ea150b494aaa40robbiew * This file is licensed under the GPL license. For the full content 50dc076565f772bb1953209fb69ea150b494aaa40robbiew * of this license, see the COPYING file at the top level of this 60dc076565f772bb1953209fb69ea150b494aaa40robbiew * source tree. 7061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek * 80dc076565f772bb1953209fb69ea150b494aaa40robbiew * Test that pthread_cond_broadcast() 90dc076565f772bb1953209fb69ea150b494aaa40robbiew * shall wakeup a high priority thread even when a low priority thread 100dc076565f772bb1953209fb69ea150b494aaa40robbiew * is running 110dc076565f772bb1953209fb69ea150b494aaa40robbiew * 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * Steps: 130dc076565f772bb1953209fb69ea150b494aaa40robbiew * 1. Create a condition variable 140dc076565f772bb1953209fb69ea150b494aaa40robbiew * 2. Create a high priority thread and make it wait on the cond 150dc076565f772bb1953209fb69ea150b494aaa40robbiew * 3. Create a low priority thread and let it busy-loop 16dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek * 4. Both low and high prio threads run on same CPU 17dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek * 5. Signal the cond from main and check that high priority thread 18dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek * got woken up and preempted low priority thread 190dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 200dc076565f772bb1953209fb69ea150b494aaa40robbiew 21dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek#include "affinity.h" 220dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h> 230dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h> 240dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h> 250dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h> 260dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <time.h> 270dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h" 28061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek#include "safe_helpers.h" 290dc076565f772bb1953209fb69ea150b494aaa40robbiew 300dc076565f772bb1953209fb69ea150b494aaa40robbiew#define TEST "5-1" 310dc076565f772bb1953209fb69ea150b494aaa40robbiew#define AREA "scheduler" 320dc076565f772bb1953209fb69ea150b494aaa40robbiew#define ERROR_PREFIX "unexpected error: " AREA " " TEST ": " 330dc076565f772bb1953209fb69ea150b494aaa40robbiew 340dc076565f772bb1953209fb69ea150b494aaa40robbiew#define HIGH_PRIORITY 10 350dc076565f772bb1953209fb69ea150b494aaa40robbiew#define LOW_PRIORITY 5 360dc076565f772bb1953209fb69ea150b494aaa40robbiew#define RUNTIME 5 370dc076565f772bb1953209fb69ea150b494aaa40robbiew#define POLICY SCHED_RR 380dc076565f772bb1953209fb69ea150b494aaa40robbiew 392c28215423293e443469a07ae7011135d058b671Garrett Cooperpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 402c28215423293e443469a07ae7011135d058b671Garrett Cooperpthread_cond_t cond = PTHREAD_COND_INITIALIZER; 410dc076565f772bb1953209fb69ea150b494aaa40robbiew 420dc076565f772bb1953209fb69ea150b494aaa40robbiew/* Flags that the threads use to indicate events */ 43d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancekstatic volatile int woken_up; 44d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancekstatic volatile int low_done; 450dc076565f772bb1953209fb69ea150b494aaa40robbiew 460dc076565f772bb1953209fb69ea150b494aaa40robbiewfloat timediff(struct timespec t2, struct timespec t1) 470dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 480dc076565f772bb1953209fb69ea150b494aaa40robbiew float diff = t2.tv_sec - t1.tv_sec; 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao diff += (t2.tv_nsec - t1.tv_nsec) / 1000000000.0; 500dc076565f772bb1953209fb69ea150b494aaa40robbiew return diff; 510dc076565f772bb1953209fb69ea150b494aaa40robbiew} 520dc076565f772bb1953209fb69ea150b494aaa40robbiew 53061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancekvoid *hi_prio_thread(void *tmp) 542c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sched_param param; 56354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int policy; 570dc076565f772bb1953209fb69ea150b494aaa40robbiew 58061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek (void) tmp; 59dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek set_affinity_single(); 600dc076565f772bb1953209fb69ea150b494aaa40robbiew 61061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_getschedparam(pthread_self(), &policy, ¶m)); 62df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper if ((policy != POLICY) || (param.sched_priority != HIGH_PRIORITY)) { 630dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error: the policy or priority not correct\n"); 640dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_UNRESOLVED); 650dc076565f772bb1953209fb69ea150b494aaa40robbiew } 660dc076565f772bb1953209fb69ea150b494aaa40robbiew 67061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_mutex_lock(&mutex)); 680dc076565f772bb1953209fb69ea150b494aaa40robbiew 690dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Block, to be woken up by the signal handler */ 70061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_cond_wait(&cond, &mutex)); 710dc076565f772bb1953209fb69ea150b494aaa40robbiew 722c28215423293e443469a07ae7011135d058b671Garrett Cooper /* This variable is unprotected because the scheduling removes 732c28215423293e443469a07ae7011135d058b671Garrett Cooper * the contention 740dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 75d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancek if (!low_done) 760dc076565f772bb1953209fb69ea150b494aaa40robbiew woken_up = 1; 770dc076565f772bb1953209fb69ea150b494aaa40robbiew 78061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_mutex_unlock(&mutex)); 790dc076565f772bb1953209fb69ea150b494aaa40robbiew return NULL; 800dc076565f772bb1953209fb69ea150b494aaa40robbiew} 810dc076565f772bb1953209fb69ea150b494aaa40robbiew 82061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancekvoid *low_prio_thread(void *tmp) 830dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct timespec start_time, current_time; 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sched_param param; 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int policy; 870dc076565f772bb1953209fb69ea150b494aaa40robbiew 88061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek (void) tmp; 89dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek set_affinity_single(); 900dc076565f772bb1953209fb69ea150b494aaa40robbiew 91061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_getschedparam(pthread_self(), &policy, ¶m)); 92df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper if ((policy != POLICY) || (param.sched_priority != LOW_PRIORITY)) { 930dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error: the policy or priority not correct\n"); 940dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_UNRESOLVED); 950dc076565f772bb1953209fb69ea150b494aaa40robbiew } 960dc076565f772bb1953209fb69ea150b494aaa40robbiew 970dc076565f772bb1953209fb69ea150b494aaa40robbiew clock_gettime(CLOCK_REALTIME, &start_time); 98d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancek while (!woken_up) { 990dc076565f772bb1953209fb69ea150b494aaa40robbiew clock_gettime(CLOCK_REALTIME, ¤t_time); 100df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper if (timediff(current_time, start_time) > RUNTIME) 1010dc076565f772bb1953209fb69ea150b494aaa40robbiew break; 1020dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1030dc076565f772bb1953209fb69ea150b494aaa40robbiew low_done = 1; 1040dc076565f772bb1953209fb69ea150b494aaa40robbiew return NULL; 1050dc076565f772bb1953209fb69ea150b494aaa40robbiew} 1060dc076565f772bb1953209fb69ea150b494aaa40robbiew 1070dc076565f772bb1953209fb69ea150b494aaa40robbiewint main() 1080dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthread_t high_id, low_id; 110dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek pthread_attr_t high_attr; 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sched_param param; 1122c28215423293e443469a07ae7011135d058b671Garrett Cooper 1130dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Create the higher priority thread */ 114061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_attr_init(&high_attr)); 1150f029d9eea2b580cd4389aecb50f016b7d5fdc04Jan Stancek SAFE_PFUNC(pthread_attr_setinheritsched(&high_attr, PTHREAD_EXPLICIT_SCHED)); 116061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_attr_setschedpolicy(&high_attr, POLICY)); 1170dc076565f772bb1953209fb69ea150b494aaa40robbiew param.sched_priority = HIGH_PRIORITY; 118061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_attr_setschedparam(&high_attr, ¶m)); 119061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_create(&high_id, &high_attr, hi_prio_thread, NULL)); 1200dc076565f772bb1953209fb69ea150b494aaa40robbiew 121dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek /* run main with same priority as low prio thread */ 1220dc076565f772bb1953209fb69ea150b494aaa40robbiew param.sched_priority = LOW_PRIORITY; 123dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek SAFE_PFUNC(pthread_setschedparam(pthread_self(), POLICY, ¶m)); 124dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek 125dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek /* Create the low priority thread (inherits sched policy from main) */ 126dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek SAFE_PFUNC(pthread_create(&low_id, NULL, low_prio_thread, NULL)); 127dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek 128dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek sleep(1); 129dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek SAFE_PFUNC(pthread_cond_broadcast(&cond)); 1300dc076565f772bb1953209fb69ea150b494aaa40robbiew 1310dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Wait for the threads to exit */ 132061df0771e1e4c42dc6d0f1efabe38b9392de48eJan Stancek SAFE_PFUNC(pthread_join(low_id, NULL)); 133d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancek if (!woken_up) { 134d9d0e9cc0cd3f5eb5f70d47177a4b9ed4a0de827Jan Stancek printf("Test FAILED: high priority was not woken up\n"); 1350dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 1360dc076565f772bb1953209fb69ea150b494aaa40robbiew } 137dadab74ec5c36fe26ea6ebd788196051e8130da6Jan Stancek SAFE_PFUNC(pthread_join(high_id, NULL)); 1380dc076565f772bb1953209fb69ea150b494aaa40robbiew 139de55e5ac14dc3e683117ae84bad34944fa7c38c6Cyril Hrubis printf("Test PASSED\n"); 1400dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_PASS); 141ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 142