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(&param, 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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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