]> rtime.felk.cvut.cz Git - rtems-devel.git/blob - rtems-tests/prioinh_posix/prio_inherit_test.c
Portable version of priority inheritance check (Posix API based).
[rtems-devel.git] / rtems-tests / prioinh_posix / prio_inherit_test.c
1 #define _GNU_SOURCE
2 #define _XOPEN_SOURCE  600
3
4 #include <sched.h>
5 #include <pthread.h>
6 #include <semaphore.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 #include "app_def.h"
13
14 pthread_mutex_t shared_with_hi_mtx;
15 pthread_mutex_t shared_with_lo_mtx;
16
17 sem_t release_hi_sem;
18 sem_t release_mid_sem;
19 sem_t release_lo_sem;
20
21 pthread_t hi_task_id;
22 pthread_t mid_task_id;
23 pthread_t lo_task_id;
24
25
26 void bad_status(int status, int fail_level, const char *text)
27 {
28   printf("ERROR: %s status %d\n", text, status);
29   exit(1);
30 }
31
32
33 void block_delay(int delay)
34 {
35   volatile int l;
36   
37   while(delay--) {
38     l = 100000;
39     while(l--);
40   }
41 }
42
43
44 void *hi_task(void *arg)
45 {
46   int status;
47
48   printf("THI created\n"); fflush(stdout);
49   while(1){
50     status=sem_wait(&release_hi_sem);
51     if(status!=0) bad_status(status, 0, "sem_wait RHI from THI");
52     printf("THI released (RHI)\n"); fflush(stdout);
53
54     status=pthread_mutex_lock(&shared_with_hi_mtx);
55     if(status!=0) bad_status(status, 0, "pthread_mutex_lock SHI from THI");
56     printf("THI obtained SHI\n"); fflush(stdout);
57
58     block_delay(100);
59
60     printf("THI going to release SHI\n"); fflush(stdout);
61     status=pthread_mutex_unlock(&shared_with_hi_mtx);
62     if(status!=0) bad_status(status, 0, "pthread_mutex_unlock SHI from THI");
63     printf("THI released SHI\n"); fflush(stdout);
64   }
65 }
66
67 void *mid_task(void *arg)
68 {
69   int status;
70
71   printf("TMID created\n"); fflush(stdout);
72   while(1){
73     status=sem_wait(&release_mid_sem);
74     if(status!=0) bad_status(status, 0, "sem_wait RMID from TMID");
75     printf("MID released (RMID)\n"); fflush(stdout);
76
77     block_delay(100);
78
79     printf("MID going to sleep\n"); fflush(stdout);
80   }
81 }
82
83 void *lo_task(void *arg)
84 {
85   int status;
86
87   printf("LO created\n"); fflush(stdout);
88   while(1){
89     status=sem_wait(&release_lo_sem);
90     if(status!=0) bad_status(status, 0, "sem_wait RLO from TLO");
91     printf("TLO released (RLO)\n"); fflush(stdout);
92
93     status=pthread_mutex_lock(&shared_with_lo_mtx);
94     if(status!=0) bad_status(status, 0, "pthread_mutex_lock SLO from TLO");
95     printf("TLO obtained SLO\n"); fflush(stdout);
96
97     block_delay(100);
98
99     printf("TLO going to release SLO\n"); fflush(stdout);
100     status=pthread_mutex_unlock(&shared_with_lo_mtx);
101     if(status!=0) bad_status(status, 0, "pthread_mutex_unlock SLO from TLO");
102     printf("TLO released SLO\n"); fflush(stdout);
103   }
104 }
105
106
107 void *Task_1(void *argument)
108 {
109   int status;
110   pthread_mutexattr_t mutexattr;
111   pthread_attr_t taskattr;
112   struct sched_param schedparam;
113
114   sleep(1);
115
116   printf("*** Starting up Task_1 ***\n");
117
118   schedparam.sched_priority = sched_get_priority_min(SCHED_FIFO) + TASK_1_PRIORITY;
119   status = pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedparam);
120   if(status!=0) bad_status(status, 0, "pthread_setschedparam" );
121
122   status = pthread_mutexattr_init(&mutexattr);
123   if(status!=0) bad_status(status, 0, "pthread_mutexattr_init" );
124   status=pthread_mutexattr_setprotocol(&mutexattr, PTHREAD_PRIO_INHERIT);
125   if(status!=0) bad_status(status, 0, "pthread_mutexattr_setprotocol" );
126
127   status=pthread_mutex_init(&shared_with_hi_mtx, &mutexattr);
128   if(status!=0) bad_status(status, 0, "pthread_mutex_init SHI" );
129
130   status=pthread_mutex_init(&shared_with_lo_mtx, &mutexattr);
131   if(status!=0) bad_status(status, 0, "pthread_mutex_init SLO" );
132
133   status=sem_init(&release_hi_sem, 0, 0);
134   if(status!=0) bad_status(status, 0, "sem_init RHI" );
135
136   status=sem_init(&release_mid_sem, 0, 0);
137   if(status!=0) bad_status(status, 0, "sem_init RMID" );
138
139   status=sem_init(&release_lo_sem, 0, 0);
140   if(status!=0) bad_status(status, 0, "sem_init RLO" );
141
142   status = pthread_attr_init(&taskattr);
143   if(status!=0) bad_status(status, 0, "pthread_attr_init" );
144   status = pthread_attr_setinheritsched(&taskattr, PTHREAD_EXPLICIT_SCHED);
145   if(status!=0) bad_status(status, 0, "pthread_attr_setinheritsched" );
146   status = pthread_attr_setschedpolicy(&taskattr, SCHED_FIFO);
147   if(status!=0) bad_status(status, 0, "pthread_attr_setschedpolicy" );
148
149   schedparam.sched_priority = sched_get_priority_min(SCHED_FIFO) + TASK_HI_PRIORITY;
150   status = pthread_attr_setschedparam(&taskattr, &schedparam);
151   if(status!=0) bad_status(status, 0, "pthread_attr_setschedparam" );
152
153   status = pthread_create(&hi_task_id, &taskattr, hi_task, NULL);
154   if(status!=0) bad_status(status, 0, "pthread_create THI\n");
155
156   schedparam.sched_priority = sched_get_priority_min(SCHED_FIFO) + TASK_MID_PRIORITY;
157   status = pthread_attr_setschedparam(&taskattr, &schedparam);
158   if(status!=0) bad_status(status, 0, "pthread_attr_setschedparam" );
159
160   status = pthread_create(&hi_task_id, &taskattr, mid_task, NULL);
161   if(status!=0) bad_status(status, 0, "pthread_create TMID\n");
162
163   schedparam.sched_priority = sched_get_priority_min(SCHED_FIFO) + TASK_LO_PRIORITY;
164   status = pthread_attr_setschedparam(&taskattr, &schedparam);
165   if(status!=0) bad_status(status, 0, "pthread_attr_setschedparam" );
166
167   status = pthread_create(&hi_task_id, &taskattr, lo_task, NULL);
168   if(status!=0) bad_status(status, 0, "pthread_create TLO\n");
169
170   sleep(1);
171
172   while(1){
173   
174     status=pthread_mutex_lock(&shared_with_lo_mtx);
175     if(status!=0) bad_status(status, 0, "pthread_mutex_lock SLO");
176     printf("1 obtained SLO\n"); fflush(stdout);
177
178     printf("1 going to release RLO\n"); fflush(stdout);
179     status=sem_post(&release_lo_sem);
180     if(status!=0) bad_status(status, 0, "sem_post RLO");
181
182     status=pthread_mutex_lock(&shared_with_hi_mtx);
183     if(status!=0) bad_status(status, 0, "pthread_mutex_lock SHI");
184     printf("1 obtained SHI\n"); fflush(stdout);
185
186     printf("1 going to release RHI\n"); fflush(stdout);
187     status=sem_post(&release_hi_sem);
188     if(status!=0) bad_status(status, 0, "sem_post RHI");
189
190     sleep(1);
191
192     printf("1 going to release RMID\n"); fflush(stdout);
193     status=sem_post(&release_mid_sem);
194     if(status!=0) bad_status(status, 0, "sem_post RMID");
195
196     block_delay(100);
197
198     printf("1 going to release SHI\n"); fflush(stdout);
199     status=pthread_mutex_unlock(&shared_with_hi_mtx);
200     if(status!=0) bad_status(status, 0, "pthread_mutex_unlock SHI");
201
202     block_delay(100);
203
204     printf("1 going to release SLO\n"); fflush(stdout);
205     status=pthread_mutex_unlock(&shared_with_lo_mtx);
206     if(status!=0) bad_status(status, 0, "pthread_mutex_unlock SLO");
207     printf("1 released both SHI and SLO\n"); fflush(stdout);
208
209     block_delay(100);
210
211     printf("1 going to sleep\n"); fflush(stdout);
212     sleep(1);
213   }
214 }
215
216 #ifndef COMPILE_FOR_RTEMS
217
218 int main(int argc, char *argv[])
219 {
220   Task_1(NULL);
221   return 0;
222 }
223
224 #endif /*COMPILE_FOR_RTEMS*/