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