1 /* Simple self-signaling test. */
2
3 #include "pthread.h"
4
5 #define DEMO_STACK_SIZE 2048
6 #if 0
7 #define MAX_MESSAGE_SIZE 50
8 #endif
9 #define DEMO_BYTE_POOL_SIZE 9120
10
11
12 /* Define the POSIX pthread object control blocks ... */
13
14 pthread_t pthread_0;
15
16 #if 0
17 pthread_t pthread_1;
18 pthread_t pthread_2;
19 pthread_t pthread_3;
20 pthread_t pthread_4;
21 pthread_t pthread_5;
22 #endif
23
24 /* Define pthread attributes objects */
25
26
27 pthread_attr_t ptattr0;
28 #if 0
29 pthread_attr_t ptattr1;
30 pthread_attr_t ptattr2;
31 pthread_attr_t ptattr3;
32 pthread_attr_t ptattr4;
33 pthread_attr_t ptattr5;
34
35
36 /* Define the message queue attribute. */
37
38 struct mq_attr queue_atrr;
39
40 /* Define a queue descriptor. */
41
42 mqd_t q_des;
43
44 /* Define a semaphore. */
45
46 sem_t *sem;
47
48 /* Define a mutex */
49
50 pthread_mutex_t mutex1;
51
52 /* Define a mutex attributes object */
53
54 pthread_mutexattr_t mta1;
55 #endif
56
57 /* Define the counters used in this test application... */
58
59 ULONG pthread_0_counter;
60 ULONG pthread_0_signal_counter;
61
62
63 #if 0
64 ULONG pthread_1_counter;
65 ULONG pthread_2_counter;
66 ULONG pthread_3_counter;
67 ULONG pthread_4_counter;
68 ULONG pthread_5_counter;
69 ULONG pthread_1_message_sent;
70 ULONG pthread_2_message_received;
71 #endif
72
73 /* Define pthread function prototypes. */
74
75 VOID *pthread_0_entry(VOID *);
76
77
78 /* Define signal handlers. */
79
80 VOID pthread_0_signal_handler(int);
81
82
83 #if 0
84 VOID *pthread_1_entry(VOID *);
85 VOID *pthread_2_entry(VOID *);
86 VOID *pthread_3_entry(VOID *);
87 VOID *pthread_4_entry(VOID *);
88 VOID *pthread_5_entry(VOID *);
89
90
91 /* Message to be sent. */
92 CHAR *msg0 = "This is a test message";
93 #endif
94 ULONG free_memory[192*1024 / sizeof(ULONG)];
95
96 /* Define main entry point. */
97
main()98 INT main()
99 {
100
101 /* Enter the ThreadX kernel. */
102 tx_kernel_enter();
103 }
104
105
106 /* Define what the initial system looks like. */
tx_application_define(VOID * first_unused_memory)107 VOID tx_application_define(VOID *first_unused_memory)
108 {
109
110 VOID* storage_ptr;
111
112
113 struct sched_param param;
114
115 #if 0
116 queue_atrr.mq_maxmsg = 124;
117 queue_atrr.mq_msgsize = MAX_MESSAGE_SIZE;
118 #endif
119
120 /* Init POSIX Wrapper */
121 storage_ptr = (VOID*) posix_initialize((VOID*)free_memory);
122
123 /* Put system definition stuff in here, e.g. pthread creates and other assoerted
124 create information. */
125
126 /* Create pthread attributes. */
127 pthread_attr_init(&ptattr0);
128 #if 0
129 pthread_attr_init(&ptattr1);
130 pthread_attr_init(&ptattr2);
131 pthread_attr_init(&ptattr3);
132 pthread_attr_init(&ptattr4);
133 pthread_attr_init(&ptattr5);
134 #endif
135
136 /* Create a sched_param structure */
137 memset(¶m, 0, sizeof(param));
138
139 /* Now create all pthreads , firstly modify respective ptheread
140 attribute with desired priority and stack start address and then create the pthread */
141
142 /* Create pthread 0. */
143 param.sched_priority = 10;
144 pthread_attr_setschedparam(&ptattr0, ¶m);
145 pthread_attr_setstackaddr(&ptattr0, storage_ptr );
146 storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE;
147 pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL);
148
149 #if 0
150 /* Create pthread 1. */
151 param.sched_priority = 15;
152 pthread_attr_setschedparam(&ptattr1, ¶m);
153 pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr );
154 storage_ptr = storage_ptr + DEMO_STACK_SIZE;
155 pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL);
156
157 /* Create pthread 2. */
158 param.sched_priority = 20;
159 pthread_attr_setschedparam(&ptattr2, ¶m);
160 pthread_attr_setstackaddr(&ptattr2, (VOID*) storage_ptr );
161 storage_ptr = storage_ptr + DEMO_STACK_SIZE;
162 pthread_create (&pthread_2, &ptattr2,pthread_2_entry,NULL);
163
164 /* Create pthread 3. */
165 param.sched_priority = 25;
166 pthread_attr_setschedparam(&ptattr3, ¶m);
167 pthread_attr_setstackaddr(&ptattr3, (VOID*) storage_ptr );
168 storage_ptr = storage_ptr + DEMO_STACK_SIZE;
169 pthread_create (&pthread_3, &ptattr3,pthread_3_entry,NULL);
170
171 /* Create pthread 4. */
172 param.sched_priority = 30;
173 pthread_attr_setschedparam(&ptattr4, ¶m);
174 pthread_attr_setstackaddr(&ptattr4, (VOID*) storage_ptr );
175 storage_ptr = storage_ptr + DEMO_STACK_SIZE;
176 pthread_create (&pthread_4, &ptattr4,pthread_4_entry,NULL);
177
178 /* Create pthread 5. */
179 param.sched_priority = 5;
180 pthread_attr_setschedparam(&ptattr5, ¶m);
181 pthread_attr_setstackaddr(&ptattr5, (VOID*) storage_ptr );
182 storage_ptr = storage_ptr + DEMO_STACK_SIZE;
183 pthread_create (&pthread_5, &ptattr5,pthread_5_entry,NULL);
184
185 /* Create a Message queue. */
186 q_des = mq_open("Queue",O_CREAT|O_RDWR,0,&queue_atrr);
187
188 /* Create a Semaphore. */
189 sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1);
190
191 /* Create a Mutex */
192 pthread_mutex_init(&mutex1, NULL);
193 #endif
194
195 }
196
error_handler(void)197 VOID error_handler(void)
198 {
199
200 while(1)
201 {
202 }
203 }
204
205
206
207 /* Define the signal handler. */
208
pthread_0_signal_handler(int signo)209 VOID pthread_0_signal_handler(int signo)
210 {
211
212 /* Check for pthread self call not pthread 0. The signal handler should appear to be
213 called from pthread 0. */
214 if (pthread_self() != pthread_0)
215 {
216
217 /* Call error handler. */
218 error_handler();
219 }
220
221 /* Check for proper signal. */
222 if (signo != 15)
223 {
224
225 /* Call error handler. */
226 error_handler();
227 }
228
229 /* Just increment the signal counter for this test. */
230 pthread_0_signal_counter++;
231 }
232
233
234
235 #if 1
236 /* Define the test pthreads */
237 INT pt0_status=0;
238 #endif
239
240 /* Self signal test. */
241
pthread_0_entry(VOID * pthread0_input)242 VOID *pthread_0_entry(VOID *pthread0_input)
243 {
244
245 // struct timespec thread_0_sleep_time={0,0};
246
247 /* Register the signal handler. */
248 pt0_status = signal(15, pthread_0_signal_handler);
249
250 /* Check for error. */
251 if (pt0_status)
252 error_handler();
253
254 /* This pthread simply sits in while-forever-sleep loop */
255 while(1)
256 {
257 /* Increment the pthread counter.*/
258 pthread_0_counter++;
259
260 /* Raise the signal. */
261 pt0_status = pthread_kill(pthread_0, 15);
262
263 /* Check for errors. */
264 if ((pt0_status) || (pthread_0_counter != pthread_0_signal_counter))
265 {
266 error_handler();
267 break;
268 }
269
270 #if 0
271 /* sleep for a while */
272 thread_0_sleep_time.tv_nsec = 999999999;
273 thread_0_sleep_time.tv_sec = 4;
274 pt0_status=nanosleep(&thread_0_sleep_time,0);
275 if(pt0_status)
276 break;
277 #endif
278
279 }
280
281 #if 1
282 return(&pt0_status);
283 #endif
284 }
285
286 #if 0
287 INT pt1_status=0;
288
289 VOID *pthread_1_entry(VOID *pthread1_input)
290 {
291
292 struct timespec thread_1_sleep_time={0,0};
293
294 /* This thread simply sends a messages to a queue shared by pthread 2. */
295 while(1)
296 {
297
298 /* Increment the thread counter. */
299 pthread_1_counter++;
300 /* Send message to queue 0. */
301 pt1_status = mq_send(q_des,msg0,strlen(msg0),3);
302
303 /* check status. */
304 if(pt1_status)
305 break;
306
307 /* Increment the message sent. */
308 pthread_1_message_sent++;
309
310 /* sleep for a while */
311 thread_1_sleep_time.tv_nsec = 200000000;
312 nanosleep(&thread_1_sleep_time,0);
313 }
314 return(&pt1_status);
315 }
316
317
318 INT pt2_status;
319
320 VOID *pthread_2_entry(VOID *pthread2_input)
321 {
322
323 CHAR msgr0[MAX_MESSAGE_SIZE];
324 ULONG priority;
325 struct timespec thread_2_sleep_time={0,0};
326
327 /* This pthread retrieves messages placed on the queue by pthread 1. */
328 while(1 )
329 {
330 /* Increment the thread counter. */
331 pthread_2_counter++;
332 pt2_status = mq_receive(q_des,msgr0,MAX_MESSAGE_SIZE,&priority);
333
334 if(pt2_status != 0)
335 break;
336
337 /* Otherwise, it is OK to increment the received message count. */
338 pthread_2_message_received++;
339 /* sleep for a while */
340 thread_2_sleep_time.tv_nsec = 200000000;
341 nanosleep(&thread_2_sleep_time,0);
342 }
343 return(&pt2_status);
344 }
345
346 INT pt3_status;
347 VOID *pthread_3_entry(VOID *pthread3_input)
348 {
349
350
351 struct timespec thread_3_sleep_time={0,0};
352
353
354 /* This function compete for ownership of semaphore_0. */
355 while(1)
356 {
357
358 /* Increment the thread counter. */
359 pthread_3_counter++;
360 /* Get the semaphore with suspension. */
361 pt3_status = sem_wait(sem);
362
363 /* Check status. */
364 if (pt3_status)
365 break;
366
367 /* Sleep for a while to hold the semaphore. */
368 thread_3_sleep_time.tv_nsec = 200000000;
369 nanosleep(&thread_3_sleep_time,0);
370
371 /* Release the semaphore. */
372 pt3_status = sem_post(sem);
373
374 /* Check status. */
375 if (pt3_status )
376 break;
377 }
378 return(&pt3_status);
379 }
380
381 INT pt4_status;
382
383 VOID *pthread_4_entry(VOID *pthread4_input)
384 {
385
386 struct timespec thread_4_sleep_time={0,0};
387
388 while(1)
389 {
390
391 /* Increment the thread counter. */
392 pthread_4_counter++;
393 /* now lock the mutex */
394 pt4_status = pthread_mutex_lock(&mutex1);
395 if (pt4_status != OK)
396 break;
397
398 /* sleep for a while */
399 thread_4_sleep_time.tv_nsec = 200000000;
400 nanosleep(&thread_4_sleep_time,0);
401
402 pt4_status = pthread_mutex_unlock(&mutex1);
403 if (pt4_status != OK)
404 break;
405 }
406 return(&pt4_status);
407 }
408
409 INT pt5_status;
410
411 VOID *pthread_5_entry(VOID *pthread5_input)
412 {
413
414 struct timespec thread_5_sleep_time={0,0};
415
416 while(1)
417 {
418 /* Increment the thread counter. */
419 pthread_5_counter++;
420 /* now lock the mutex */
421 pt5_status = pthread_mutex_lock(&mutex1);
422 if (pt5_status != OK)
423 break;
424
425 /* sleep for a while */
426 thread_5_sleep_time.tv_nsec = 20000000;
427 nanosleep(&thread_5_sleep_time,0);
428 pt5_status = pthread_mutex_unlock(&mutex1);
429 if (pt5_status != OK)
430 break;
431 }
432 return(&pt5_status);
433 }
434 #endif
435
436
437