1 /* Simple resume from signal handler test.  */
2 
3 #include   "pthread.h"
4 
5 #define     DEMO_STACK_SIZE         2048
6 #define     DEMO_BYTE_POOL_SIZE     9120
7 
8 
9 /* Define the POSIX pthread object control blocks ... */
10 
11 pthread_t               pthread_0;
12 pthread_t               pthread_1;
13 
14 
15 /* Define pthread attributes objects */
16 
17 
18 pthread_attr_t          ptattr0;
19 pthread_attr_t          ptattr1;
20 
21 
22 /* Define a semaphore.                 */
23 
24 sem_t                   *sem;
25 
26 
27 /* Define the counters used in this test application...  */
28 
29 ULONG     pthread_0_counter;
30 ULONG     pthread_0_signal_counter15;
31 ULONG     pthread_0_signal_counter14;
32 ULONG     pthread_0_signal_counter13;
33 
34 ULONG     pthread_1_counter;
35 
36 
37 /* Define pthread function prototypes.  */
38 
39 VOID    *pthread_0_entry(VOID *);
40 VOID    *pthread_1_entry(VOID *);
41 
42 
43 /* Define signal handlers.  */
44 
45 VOID    pthread_0_signal_handler15(int);
46 VOID    pthread_0_signal_handler14(int);
47 VOID    pthread_0_signal_handler13(int);
48 ULONG free_memory[192*1024 / sizeof(ULONG)];
49 
50 /* Define main entry point.  */
51 
main()52 INT main()
53 {
54 
55     /* Enter the ThreadX kernel.  */
56     tx_kernel_enter();
57 }
58 
59 
60 /* Define what the initial system looks like.  */
tx_application_define(VOID * first_unused_memory)61 VOID tx_application_define(VOID *first_unused_memory)
62 {
63 
64     VOID* storage_ptr;
65 
66 
67 struct sched_param  param;
68 
69 
70     /* Init POSIX Wrapper */
71     storage_ptr = (VOID*) posix_initialize((VOID*)free_memory);
72 
73     /* Put system definition stuff in here, e.g. pthread creates and other assoerted
74        create information. */
75 
76     /* Create pthread attributes.  */
77     pthread_attr_init(&ptattr0);
78     pthread_attr_init(&ptattr1);
79 
80     /* Create a sched_param structure */
81     memset(&param, 0, sizeof(param));
82 
83     /* Now create all pthreads , firstly modify respective ptheread
84        attribute with desired priority and stack start address and then create the pthread */
85 
86     /* Create pthread 0.  */
87     param.sched_priority = 15;
88     pthread_attr_setschedparam(&ptattr0, &param);
89     pthread_attr_setstackaddr(&ptattr0,  storage_ptr );
90     storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE;
91     pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL);
92 
93 
94     /* Create pthread 1.  */
95     param.sched_priority = 10;
96     pthread_attr_setschedparam(&ptattr1, &param);
97     pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr );
98     storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE;
99     pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL);
100 
101 
102     /* Create a Semaphore.  */
103     sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1);
104 }
105 
106 
error_handler(void)107 VOID    error_handler(void)
108 {
109 
110     while(1)
111     {
112     }
113 }
114 
115 
116 
117 /* Define the signal handlers.  */
118 
119 
pthread_0_signal_handler13(int signo)120 VOID  pthread_0_signal_handler13(int signo)
121 {
122 
123     /* Check for pthread self call not pthread 0. The signal handler should appear to be
124        called from pthread 0.  */
125     if (pthread_self() != pthread_0)
126     {
127 
128         /* Call error handler.  */
129         error_handler();
130     }
131 
132     /* Check for proper signal.  */
133     if (signo != 13)
134     {
135 
136         /* Call error handler.  */
137         error_handler();
138     }
139 
140     /* Just increment the signal counter for this test.  */
141     pthread_0_signal_counter13++;
142 
143     /* Release the semaphore, which will wakeup pthread 0.  */
144     sem_post(sem);
145 }
146 
147 
pthread_0_signal_handler14(int signo)148 VOID  pthread_0_signal_handler14(int signo)
149 {
150 
151     /* Check for pthread self call not pthread 0. The signal handler should appear to be
152        called from pthread 0.  */
153     if (pthread_self() != pthread_0)
154     {
155 
156         /* Call error handler.  */
157         error_handler();
158     }
159 
160     /* Check for proper signal.  */
161     if (signo != 14)
162     {
163 
164         /* Call error handler.  */
165         error_handler();
166     }
167 
168     /* Just increment the signal counter for this test.  */
169     pthread_0_signal_counter14++;
170 
171     /* Raise another signal for nesting test.  */
172     pthread_kill(pthread_0, 13);
173 }
174 
175 
pthread_0_signal_handler15(int signo)176 VOID  pthread_0_signal_handler15(int signo)
177 {
178 
179     /* Check for pthread self call not pthread 0. The signal handler should appear to be
180        called from pthread 0.  */
181     if (pthread_self() != pthread_0)
182     {
183 
184         /* Call error handler.  */
185         error_handler();
186     }
187 
188     /* Check for proper signal.  */
189     if (signo != 15)
190     {
191 
192         /* Call error handler.  */
193         error_handler();
194     }
195 
196     /* Just increment the signal counter for this test.  */
197     pthread_0_signal_counter15++;
198 
199     /* Raise another signal for nesting test.  */
200     pthread_kill(pthread_0, 14);
201 }
202 
203 
204 /* Define the test pthreads */
205 INT pt0_status=0;
206 
207 
208 /* Self signal test.  */
209 
pthread_0_entry(VOID * pthread0_input)210 VOID    *pthread_0_entry(VOID *pthread0_input)
211 {
212 
213     /* Register the signal handlers.  */
214     pt0_status =  signal(15, pthread_0_signal_handler15);
215 
216     /* Check for error.  */
217     if (pt0_status)
218         error_handler();
219 
220     pt0_status =  signal(14, pthread_0_signal_handler14);
221 
222     /* Check for error.  */
223     if (pt0_status)
224         error_handler();
225 
226     pt0_status =  signal(13, pthread_0_signal_handler13);
227 
228     /* Check for error.  */
229     if (pt0_status)
230         error_handler();
231 
232 
233     /* Get the semaphore with suspension.  */
234     pt0_status = sem_wait(sem);
235 
236     /* This pthread simply sits in while-forever-sleep loop */
237     while(1)
238     {
239         /* Increment the pthread counter.*/
240         pthread_0_counter++;
241 
242         /* Get the semaphore with suspension.  */
243         pt0_status = sem_wait(sem);
244 
245         /* Check for errors.  */
246         if ((pt0_status) ||
247             (pthread_0_counter != pthread_0_signal_counter15) ||
248             (pthread_0_counter != pthread_0_signal_counter14) ||
249             (pthread_0_counter != pthread_0_signal_counter13))
250         {
251 
252             /* In this test, this thread should never resume!  */
253             error_handler();
254 
255             /* Break out of the loop.  */
256             break;
257         }
258     }
259 
260     return(&pt0_status);
261 }
262 
263 
264 INT    pt1_status=0;
265 
pthread_1_entry(VOID * pthread1_input)266 VOID    *pthread_1_entry(VOID *pthread1_input)
267 {
268 
269 
270     /* This thread simply sends a messages to a queue shared by pthread 2.  */
271     while(1)
272     {
273 
274         /* Increment the thread counter.  */
275         pthread_1_counter++;
276 
277         /* Raise the first signal for pthread 0.  */
278         pt1_status =  pthread_kill(pthread_0, 15);
279 
280         /* Check for errors.  */
281         if ((pt1_status) ||
282             (pthread_0_counter != (pthread_1_counter+1)) ||
283             (pthread_1_counter != pthread_0_signal_counter15) ||
284             (pthread_1_counter != pthread_0_signal_counter14) ||
285             (pthread_1_counter != pthread_0_signal_counter13))
286         {
287 
288             error_handler();
289             break;
290         }
291     }
292 
293     return(&pt1_status);
294 }
295 
296