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(¶m, 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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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