16acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/****************************************************************************** 26acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 31378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak * Copyright © International Business Machines Corp., 2005, 2008 46acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 56acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * This program is free software; you can redistribute it and/or modify 66acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * it under the terms of the GNU General Public License as published by 76acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * the Free Software Foundation; either version 2 of the License, or 86acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * (at your option) any later version. 96acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 106acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * This program is distributed in the hope that it will be useful, 116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * but WITHOUT ANY WARRANTY; without even the implied warranty of 126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 136acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * the GNU General Public License for more details. 146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * You should have received a copy of the GNU General Public License 166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * along with this program; if not, write to the Free Software 174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * NAME 206acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * testpi-4.c 216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * DESCRIPTION 235305c4a10cf26799c81e6f0362750988457d3002Subrata Modak * This testcase verifies that the SCHED_OTHER thread can preempt 245305c4a10cf26799c81e6f0362750988457d3002Subrata Modak * the SCHED_RR thread via priority inheritance. 256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 266acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * USAGE: 276acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * Use run_auto.sh script in current directory to build and run test. 286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * AUTHOR 306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 316acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * HISTORY 3365f7070cb3f67eba009e68413187727f508623e1Subrata Modak * 2010-06-29 Thread synchronization changes by using 347d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper * conditional variables by Gowrishankar. 357d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper * by Gowrishankar <gowrishankar.m@in.ibm.com> 366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * 376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *****************************************************************************/ 386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdio.h> 406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdlib.h> 416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <string.h> 426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sched.h> 436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <errno.h> 446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <pthread.h> 456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sys/types.h> 466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sys/syscall.h> 476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <unistd.h> 486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <librttest.h> 496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 501378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modakpthread_barrier_t barrier; 516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid usage(void) 536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 54b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak rt_help(); 55b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("testpi-4 specific options:\n"); 566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint parse_args(int c, char *v) 596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 60b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak int handled = 1; 61b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak switch (c) { 62b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak case 'h': 63b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak usage(); 64b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak exit(0); 65b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak default: 66b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak handled = 0; 67b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak break; 68b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 69b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak return handled; 706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 726acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint gettid(void) 736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 74b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak return syscall(__NR_gettid); 756acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 766acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotypedef void *(*entrypoint_t) (void *); 786acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakpthread_mutex_t *glob_mutex; 7965f7070cb3f67eba009e68413187727f508623e1Subrata Modakstatic pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; 8065f7070cb3f67eba009e68413187727f508623e1Subrata Modakstatic pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER; 816acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 82b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_nonrt(void *arg) 836acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 84b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak struct thread *pthr = (struct thread *)arg; 85bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak int i, tid = gettid(); 86b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 87b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Thread %d started running with priority %d\n", tid, 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthr->priority); 89b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_mutex_lock(glob_mutex); 90b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Thread %d at start pthread pol %d pri %d - Got global lock\n", 91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao tid, pthr->policy, pthr->priority); 9265f7070cb3f67eba009e68413187727f508623e1Subrata Modak 9365f7070cb3f67eba009e68413187727f508623e1Subrata Modak /* Wait for other RT threads to start up */ 94b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_barrier_wait(&barrier); 95b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 9665f7070cb3f67eba009e68413187727f508623e1Subrata Modak /* Wait for the high priority noise thread to start and signal us */ 9765f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_lock(&cond_mutex); 9865f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_cond_wait(&cond_var, &cond_mutex); 9965f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_unlock(&cond_mutex); 10065f7070cb3f67eba009e68413187727f508623e1Subrata Modak 101b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak for (i = 0; i < 10000; i++) { 102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (i % 100 == 0) { 103b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Thread %d loop %d pthread pol %d pri %d\n", 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao tid, i, pthr->policy, pthr->priority); 105b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak fflush(NULL); 106b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 107bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak busy_work_ms(1); 108b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 109b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_mutex_unlock(glob_mutex); 110b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak return NULL; 1116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 113b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_rt(void *arg) 1146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 115b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak struct thread *pthr = (struct thread *)arg; 116bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak int i, tid = gettid(); 117b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Thread %d started running with prio %d\n", tid, pthr->priority); 119b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_barrier_wait(&barrier); 120b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_mutex_lock(glob_mutex); 121b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Thread %d at start pthread pol %d pri %d - Got global lock\n", 122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao tid, pthr->policy, pthr->priority); 123b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 124b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak /* we just use the mutex as something to slow things down, 125b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak * say who we are and then do nothing for a while. The aim 126b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak * of this is to show that high priority threads make more 127b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak * progress than lower priority threads.. 128b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak */ 129b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak for (i = 0; i < 1000; i++) { 130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (i % 100 == 0) { 131b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Thread %d loop %d pthread pol %d pri %d\n", 132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao tid, i, pthr->policy, pthr->priority); 133b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak fflush(NULL); 134b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 135bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak busy_work_ms(1); 136b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 137b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_mutex_unlock(glob_mutex); 138b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak return NULL; 1396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 141b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_noise(void *arg) 1426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{ 143b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak struct thread *pthr = (struct thread *)arg; 144bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak int i, tid = gettid(); 145b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Noise Thread started running with prio %d\n", pthr->priority); 147b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak pthread_barrier_wait(&barrier); 148b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Give the other threads time to wait on the condition variable. */ 15065f7070cb3f67eba009e68413187727f508623e1Subrata Modak usleep(1000); 15165f7070cb3f67eba009e68413187727f508623e1Subrata Modak 15265f7070cb3f67eba009e68413187727f508623e1Subrata Modak /* Noise thread begins the test */ 15365f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_lock(&cond_mutex); 15465f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_cond_broadcast(&cond_var); 15565f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_unlock(&cond_mutex); 15665f7070cb3f67eba009e68413187727f508623e1Subrata Modak 157b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak for (i = 0; i < 10000; i++) { 158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (i % 100 == 0) { 159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Noise Thread %d loop %d pthread pol %d " 160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "pri %d\n", tid, i, pthr->policy, 161354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pthr->priority); 162b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak fflush(NULL); 163b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 164bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak busy_work_ms(1); 165b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 166b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak return NULL; 1676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak} 1686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak 1696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/* 1706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * Test pthread creation at different thread priorities. 1716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak */ 172b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakint main(int argc, char *argv[]) 173b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak{ 174a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak int i, retc, nopi = 0; 175b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak cpu_set_t mask; 176b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak CPU_ZERO(&mask); 177b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak CPU_SET(0, &mask); 178b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak setup(); 179b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 180b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak rt_init("h", parse_args, argc, argv); 181b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 182b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak retc = pthread_barrier_init(&barrier, NULL, 5); 183b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak if (retc) { 184b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("pthread_barrier_init failed: %s\n", strerror(retc)); 185b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak exit(retc); 186b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 187b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 188b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak retc = sched_setaffinity(0, sizeof(mask), &mask); 189b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak if (retc < 0) { 190b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Main Thread: Can't set affinity: %d %s\n", retc, 191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao strerror(retc)); 192b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak exit(-1); 193b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 194b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak for (i = 0; i < argc; i++) { 195b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak if (strcmp(argv[i], "nopi") == 0) 196b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak nopi = 1; 197b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 198b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 199b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Start %s\n", argv[0]); 200b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 201b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak glob_mutex = malloc(sizeof(pthread_mutex_t)); 202b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak if (glob_mutex == NULL) { 203b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Malloc failed\n"); 204b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak exit(errno); 205b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak } 206b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 207a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak if (!nopi) 208a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak init_pi_mutex(glob_mutex); 209b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 210b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak create_other_thread(func_nonrt, NULL); 211b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak create_rr_thread(func_rt, NULL, 20); 212b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak create_rr_thread(func_rt, NULL, 30); 213b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak create_rr_thread(func_rt, NULL, 40); 214b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak create_rr_thread(func_noise, NULL, 40); 215b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 216b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Joining threads\n"); 217b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak join_threads(); 218b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak printf("Done\n"); 219b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak 22065f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_destroy(glob_mutex); 22165f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_mutex_destroy(&cond_mutex); 22265f7070cb3f67eba009e68413187727f508623e1Subrata Modak pthread_cond_destroy(&cond_var); 223ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis 224ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis return 0; 225ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis} 226