Home | History | Annotate | Download | only in pthread_attr_setschedpolicy
      1 /*
      2  *
      3  *   Copyright (c) Novell Inc. 2011
      4  *
      5  *   This program is free software;  you can redistribute it and/or modify
      6  *   it under the terms in version 2 of the GNU General Public License as published by
      7  *   the Free Software Foundation.
      8  *
      9  *   This program is distributed in the hope that it will be useful,
     10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  *   the GNU General Public License for more details.
     13  *
     14  *   You should have received a copy of the GNU General Public License
     15  *   along with this program;  if not, write to the Free Software
     16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  *
     18  *   Author:  Peter W. Morreale <pmorreale AT novell DOT com>
     19  *
     20  *   Date:  20/05/2011
     21  */
     22 
     23 #include "affinity.h"
     24 
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <pthread.h>
     28 #include <unistd.h>
     29 #include <stdlib.h>
     30 #include <errno.h>
     31 #include <posixtest.h>
     32 
     33 /* Priorities for the threads, must be unique, non-zero, and ordered */
     34 #define PRIO_HIGH	20
     35 #define PRIO_MED	10
     36 #define PRIO_LOW	5
     37 #define PRIO_MAIN	1
     38 
     39 static int priorities[3];
     40 
     41 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     42 static pthread_mutex_t c_mutex = PTHREAD_MUTEX_INITIALIZER;
     43 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
     44 
     45 static int thread_started;
     46 
     47 #define FAIL_AND_EXIT(f, rc) { \
     48 	printf("Failed: function: %s status: %s(%u)\n", f, strerror(rc), rc); \
     49 	exit(PTS_UNRESOLVED); \
     50 }
     51 
     52 static void *thread_func(void *data)
     53 {
     54 	struct sched_param sp;
     55 	int policy;
     56 	int rc;
     57 
     58 	rc = pthread_getschedparam(pthread_self(), &policy, &sp);
     59 	if (rc)
     60 		FAIL_AND_EXIT("pthread_getschedparam()", rc);
     61 
     62 	rc = pthread_mutex_lock(&c_mutex);
     63 	if (rc)
     64 		FAIL_AND_EXIT("pthread_mutex_lock()", rc);
     65 	thread_started = 1;
     66 	rc = pthread_cond_signal(&cond);
     67 	if (rc)
     68 		FAIL_AND_EXIT("pthread_cond_signal()", rc);
     69 	rc = pthread_mutex_unlock(&c_mutex);
     70 	if (rc)
     71 		FAIL_AND_EXIT("pthread_mutex_unlock()", rc);
     72 
     73 	rc = pthread_mutex_lock(&mutex);
     74 	if (rc)
     75 		FAIL_AND_EXIT("pthread_mutex_lock()", rc);
     76 
     77 	/* Stuff the priority in execution order */
     78 	if (!priorities[0])
     79 		priorities[0] = sp.sched_priority;
     80 	else if (!priorities[1])
     81 		priorities[1] = sp.sched_priority;
     82 	else
     83 		priorities[2] = sp.sched_priority;
     84 
     85 	rc = pthread_mutex_unlock(&mutex);
     86 	if (rc)
     87 		FAIL_AND_EXIT("pthread_mutex_unlock()", rc);
     88 
     89 	return (void *)(long)rc;
     90 }
     91 
     92 static int create_thread(int prio, pthread_t * tid)
     93 {
     94 	int rc;
     95 	struct sched_param sp;
     96 	pthread_attr_t attr;
     97 
     98 	rc = pthread_attr_init(&attr);
     99 	if (rc != 0)
    100 		FAIL_AND_EXIT("pthread_attr_init()", rc);
    101 
    102 	rc = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
    103 	if (rc != 0)
    104 		FAIL_AND_EXIT("pthread_attr_setschedpolicy()", rc);
    105 
    106 	rc = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    107 	if (rc != 0)
    108 		FAIL_AND_EXIT("pthread_attr_setinheritsched()", rc);
    109 
    110 	sp.sched_priority = prio;
    111 	rc = pthread_attr_setschedparam(&attr, &sp);
    112 	if (rc != 0)
    113 		FAIL_AND_EXIT("pthread_attr_setschedparam()", rc);
    114 
    115 	thread_started = 0;
    116 
    117 	rc = pthread_create(tid, &attr, thread_func, NULL);
    118 	if (rc)
    119 		FAIL_AND_EXIT("pthread_create()", rc);
    120 
    121 	rc = pthread_mutex_lock(&c_mutex);
    122 	if (rc)
    123 		FAIL_AND_EXIT("pthread_mutex_lock()", rc);
    124 	while (!thread_started) {
    125 		rc = pthread_cond_wait(&cond, &c_mutex);
    126 		if (rc)
    127 			FAIL_AND_EXIT("pthread_cond_wait()", rc);
    128 	}
    129 	rc = pthread_mutex_unlock(&c_mutex);
    130 	if (rc)
    131 		FAIL_AND_EXIT("pthread_mutex_unlock()", rc);
    132 
    133 	pthread_attr_destroy(&attr);
    134 
    135 	return 0;
    136 }
    137 
    138 int main(void)
    139 {
    140 	int status;
    141 	int rc;
    142 	void *r1;
    143 	void *r2;
    144 	void *r3;
    145 	pthread_t t1;
    146 	pthread_t t2;
    147 	pthread_t t3;
    148 	struct sched_param sp;
    149 
    150 	status = PTS_UNRESOLVED;
    151 
    152 
    153 	rc = set_affinity_single();
    154 	if (rc)
    155 		FAIL_AND_EXIT("set_affinity_single", errno);
    156 
    157 	sp.sched_priority = PRIO_MAIN;
    158 	rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp);
    159 	if (rc)
    160 		FAIL_AND_EXIT("pthread_setschedparam()", rc);
    161 
    162 	rc = pthread_mutex_lock(&mutex);
    163 	if (rc)
    164 		FAIL_AND_EXIT("pthread_mutex_lock()", rc);
    165 
    166 	rc = create_thread(PRIO_LOW, &t3);
    167 	if (rc)
    168 		FAIL_AND_EXIT("create_thread LOW", rc);
    169 
    170 	rc = create_thread(PRIO_MED, &t2);
    171 	if (rc)
    172 		FAIL_AND_EXIT("create_thread MED", rc);
    173 
    174 	rc = create_thread(PRIO_HIGH, &t1);
    175 	if (rc)
    176 		FAIL_AND_EXIT("create_thread HIGH", rc);
    177 
    178 	rc = pthread_mutex_unlock(&mutex);
    179 	if (rc)
    180 		FAIL_AND_EXIT("pthread_mutex_unlock()", rc);
    181 
    182 	rc = pthread_join(t1, &r1);
    183 	if (rc)
    184 		FAIL_AND_EXIT("pthread_join(t1)", rc);
    185 
    186 	rc = pthread_join(t2, &r2);
    187 	if (rc)
    188 		FAIL_AND_EXIT("pthread_join(t2)", rc);
    189 
    190 	rc = pthread_join(t3, &r3);
    191 	if (rc)
    192 		FAIL_AND_EXIT("pthread_join(t3)", rc);
    193 
    194 	/* priorities must be high to low */
    195 	status = PTS_FAIL;
    196 	if (priorities[0] != PRIO_HIGH)
    197 		printf("Failed: first is prio: %u, should be: %u\n",
    198 		       priorities[0], PRIO_HIGH);
    199 	else if (priorities[1] != PRIO_MED)
    200 		printf("Failed: second is prio: %u, should be: %u\n",
    201 		       priorities[1], PRIO_MED);
    202 	else if (priorities[2] != PRIO_LOW)
    203 		printf("Failed: third is prio: %u, should be: %u\n",
    204 		       priorities[2], PRIO_LOW);
    205 	else
    206 		status = PTS_PASS;
    207 
    208 	if (status == PTS_PASS)
    209 		printf("Test PASSED\n");
    210 
    211 	return status;
    212 }
    213