1 /* This test is designed to test the mutex create/delete and immediate
2    return gets and puts.  */
3 
4 #include   <stdio.h>
5 #include   "tx_api.h"
6 #include   "tx_mutex.h"
7 
8 
9 typedef struct MUTEX_MEMORY_TEST_STRUCT
10 {
11     ULONG           first;
12     ULONG           second;
13     TX_MUTEX        mutex;
14     ULONG           next_to_last;
15     ULONG           last;
16 
17 } MUTEX_MEMORY_TEST;
18 
19 static  MUTEX_MEMORY_TEST   mutex_memory;
20 
21 
22 /* Define the ISR dispatch.  */
23 
24 extern VOID    (*test_isr_dispatch)(void);
25 
26 
27 static unsigned long   thread_0_counter =  0;
28 static unsigned long   thread_1_counter =  0;
29 static TX_THREAD       thread_0;
30 static TX_THREAD       thread_1;
31 static TX_THREAD       thread_2;
32 static TX_THREAD       thread_3;
33 static TX_THREAD       thread_4;
34 
35 static TX_MUTEX        mutex_0;
36 static TX_MUTEX        mutex_1;
37 static TX_MUTEX        mutex_2;
38 static TX_MUTEX        mutex_3;
39 static TX_MUTEX        mutex_4;
40 static TX_MUTEX        mutex_5;
41 static TX_MUTEX        mutex_6;
42 static TX_MUTEX        mutex_7;
43 static TX_MUTEX        mutex_8;
44 
45 static TX_TIMER        timer_0;
46 
47 
48 static unsigned long error =  0;
49 static unsigned long timer_executed =  0;
50 static unsigned long isr_executed =  0;
51 
52 
53 /* Define thread prototypes.  */
54 
55 static void    thread_0_entry(ULONG thread_input);
56 static void    thread_1_entry(ULONG thread_input);
57 static void    thread_2_entry(ULONG thread_input);
58 static void    thread_3_entry(ULONG thread_input);
59 static void    thread_4_entry(ULONG thread_input);
60 
61 UINT        _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size);
62 
63 
64 /* Prototype for test control return.  */
65 
66 void  test_control_return(UINT status);
67 
68 
69 /* Define the timer for this test.  */
70 
timer_entry(ULONG i)71 static void    timer_entry(ULONG i)
72 {
73 
74 #ifndef TX_DISABLE_ERROR_CHECKING
75 
76 UINT    status;
77 
78     /* Attempt to create a mutex from a timer.  */
79     status =  tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
80 
81     /* Check status.  */
82     if (status != TX_CALLER_ERROR)
83     {
84 
85         /* Error!  */
86         error++;
87     }
88 
89     /* Attempt to delete a mutex from a timer.  */
90     status =  tx_mutex_delete(&mutex_2);
91 
92     /* Check status.  */
93     if (status != TX_CALLER_ERROR)
94     {
95 
96         /* Error!  */
97         error++;
98     }
99 
100     /* Attempt to get from mutex from a timer with suspension.   */
101     status =  tx_mutex_get(&mutex_2, 100);
102 
103     /* Check status.  */
104     if (status != TX_WAIT_ERROR)
105     {
106 
107         /* Error!  */
108         error++;
109     }
110 
111     timer_executed =  1;
112 #endif
113 }
114 
115 /* Define the ISR dispatch routine.  */
116 
test_isr(void)117 static void    test_isr(void)
118 {
119 
120 #ifndef TX_DISABLE_ERROR_CHECKING
121 
122 UINT    status;
123 
124 
125     /* Attempt to create a mutex from an ISR.  */
126     status =  tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
127 
128     /* Check status.  */
129     if (status != TX_CALLER_ERROR)
130     {
131 
132         /* Error!  */
133         error++;
134     }
135 
136     /* Attempt to delete a mutex from an ISR.  */
137     status =  tx_mutex_delete(&mutex_2);
138 
139     /* Check status.  */
140     if (status != TX_CALLER_ERROR)
141     {
142 
143         /* Error!  */
144         error++;
145     }
146 
147     /* Attempt to get from mutex from an ISR with suspension.   */
148     status =  tx_mutex_get(&mutex_2, 100);
149 
150     /* Check status.  */
151     if (status != TX_WAIT_ERROR)
152     {
153 
154         /* Error!  */
155         error++;
156     }
157 
158     /* Attempt to get from mutex from an ISR without suspension.   */
159     status =  tx_mutex_get(&mutex_2, TX_NO_WAIT);
160 
161     /* Check status.  */
162     if (status != TX_CALLER_ERROR)
163     {
164 
165         /* Error!  */
166         error++;
167     }
168 
169     /* Attempt to put a mutex from an ISR.  */
170     status =  tx_mutex_put(&mutex_2);
171 
172     /* Check status.  */
173     if (status != TX_CALLER_ERROR)
174     {
175 
176         /* Error!  */
177         error++;
178     }
179 
180     isr_executed =  1;
181 #endif
182 }
183 
184 
185 
186 /* Define what the initial system looks like.  */
187 
188 #ifdef CTEST
test_application_define(void * first_unused_memory)189 void test_application_define(void *first_unused_memory)
190 #else
191 void    threadx_mutex_basic_application_define(void *first_unused_memory)
192 #endif
193 {
194 
195 UINT    status;
196 CHAR    *pointer;
197 
198     /* Put first available memory address into a character pointer.  */
199     pointer =  (CHAR *) first_unused_memory;
200 
201     /* Put system definition stuff in here, e.g. thread creates and other assorted
202        create information.  */
203 
204     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
205             pointer, TEST_STACK_SIZE_PRINTF,
206             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
207     pointer = pointer + TEST_STACK_SIZE_PRINTF;
208 
209 
210     status +=  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
211             pointer, TEST_STACK_SIZE_PRINTF,
212             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
213     pointer = pointer + TEST_STACK_SIZE_PRINTF;
214 
215     status +=  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
216             pointer, TEST_STACK_SIZE_PRINTF,
217             18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
218     pointer = pointer + TEST_STACK_SIZE_PRINTF;
219 
220     status +=  tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
221             pointer, TEST_STACK_SIZE_PRINTF,
222             18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
223     pointer = pointer + TEST_STACK_SIZE_PRINTF;
224 
225     status +=  tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
226             pointer, TEST_STACK_SIZE_PRINTF,
227             18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
228     pointer = pointer + TEST_STACK_SIZE_PRINTF;
229 
230     /* Check for status.  */
231     if (status != TX_SUCCESS)
232     {
233 
234         printf("Running Mutex Basic Test............................................ ERROR #1\n");
235         test_control_return(1);
236     }
237 
238     /* Create a mutex.  */
239     status =  tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
240 
241     /* Check for status.  */
242     if (status != TX_SUCCESS)
243     {
244 
245         printf("Running Mutex Basic Test............................................ ERROR #2\n");
246         test_control_return(1);
247     }
248 
249     /* Create another mutex.  */
250     status =  tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
251 
252     /* Check for status.  */
253     if (status != TX_SUCCESS)
254     {
255 
256         printf("Running Mutex Basic Test............................................ ERROR #3\n");
257         test_control_return(1);
258     }
259 
260     /* Create another mutex.  */
261     status =  tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
262 
263     /* Check for status.  */
264     if (status != TX_SUCCESS)
265     {
266 
267         printf("Running Mutex Basic Test............................................ ERROR #4\n");
268         test_control_return(1);
269     }
270 
271     /* Create another mutex.  */
272     status =  tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
273 
274     /* Check for status.  */
275     if (status != TX_SUCCESS)
276     {
277 
278         printf("Running Mutex Basic Test............................................ ERROR #5\n");
279         test_control_return(1);
280     }
281 
282     /* Create another mutex.  */
283     status =  tx_mutex_create(&mutex_8, "mutex 8", TX_NO_INHERIT);
284 
285     /* Check for status.  */
286     if (status != TX_SUCCESS)
287     {
288 
289         printf("Running Mutex Basic Test............................................ ERROR #5a\n");
290         test_control_return(1);
291     }
292 }
293 
294 
295 
296 /* Define the test threads.  */
297 
thread_0_entry(ULONG thread_input)298 static void    thread_0_entry(ULONG thread_input)
299 {
300 
301 UINT    status;
302 
303 
304     /* Inform user.  */
305     printf("Running Mutex Basic Test............................................ ");
306 
307     /* Perform mutex memory test.  */
308     mutex_memory.first =        0x11223344;
309     mutex_memory.second =       0x55667788;
310     mutex_memory.next_to_last = 0x99aabbcc;
311     mutex_memory.last =         0xddeeff00;
312 
313     /* Create the semaphore.  */
314     status =  tx_mutex_create(&mutex_memory.mutex, "mutex memory", TX_INHERIT);
315     tx_mutex_delete(&mutex_memory.mutex);
316 
317     /* Check for status.  */
318     if ((status != TX_SUCCESS) ||
319         (mutex_memory.first != 0x11223344) ||
320         (mutex_memory.second != 0x55667788) ||
321         (mutex_memory.next_to_last != 0x99aabbcc) ||
322         (mutex_memory.last != 0xddeeff00))
323     {
324 
325         /* Mutex error.  */
326         printf("ERROR #6\n");
327         test_control_return(1);
328     }
329 
330     /* Increment thread 0 counter.  */
331     thread_0_counter++;
332 
333 #ifndef TX_DISABLE_ERROR_CHECKING
334 
335     /* Attempt to create a mutex with a NULL pointer.  */
336     status =  tx_mutex_create(TX_NULL, "mutex 2", TX_INHERIT);
337 
338     /* Check status.  */
339     if (status != TX_MUTEX_ERROR)
340     {
341 
342         /* Mutex error.  */
343         printf("ERROR #7\n");
344         test_control_return(1);
345     }
346 
347     /* Attempt to create a mutex with a bad size.  */
348     status =  _txe_mutex_create(&mutex_5, "mutex 5", TX_INHERIT, (sizeof(TX_MUTEX)+1));
349 
350     /* Check status.  */
351     if (status != TX_MUTEX_ERROR)
352     {
353 
354         /* Mutex error.  */
355         printf("ERROR #8\n");
356         test_control_return(1);
357     }
358 
359     /* Attempt to create a mutex that has already been created.  */
360     status =  tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
361 
362     /* Check status.  */
363     if (status != TX_MUTEX_ERROR)
364     {
365 
366         /* Mutex error.  */
367         printf("ERROR #9\n");
368         test_control_return(1);
369     }
370 
371     /* Attempt to create a mutex with a bad inheritance option.  */
372     status =  tx_mutex_create(&mutex_4, "mutex 4", 14);
373 
374     /* Check status.  */
375     if (status != TX_INHERIT_ERROR)
376     {
377 
378         /* Mutex error.  */
379         printf("ERROR #10\n");
380         test_control_return(1);
381     }
382 
383     /* Attempt to delete a mutex with a NULL pointer.  */
384     status =  tx_mutex_delete(TX_NULL);
385 
386     /* Check status.  */
387     if (status != TX_MUTEX_ERROR)
388     {
389 
390         /* Mutex error.  */
391         printf("ERROR #11\n");
392         test_control_return(1);
393     }
394 
395     /* Attempt to delete a non-created mutex.  */
396     mutex_4.tx_mutex_id =  0;
397     status =  tx_mutex_delete(&mutex_4);
398 
399     /* Check status.  */
400     if (status != TX_MUTEX_ERROR)
401     {
402 
403         /* Mutex error.  */
404         printf("ERROR #12\n");
405         test_control_return(1);
406     }
407 
408     /* Attempt to get a mutex with a NULL pointer.  */
409     status =  tx_mutex_get(TX_NULL, TX_NO_WAIT);
410 
411     /* Check status.  */
412     if (status != TX_MUTEX_ERROR)
413     {
414 
415         /* Mutex error.  */
416         printf("ERROR #13\n");
417         test_control_return(1);
418     }
419 
420     /* Attempt to get a non-created mutex.  */
421     mutex_4.tx_mutex_id =  0;
422     status =  tx_mutex_get(&mutex_4, TX_NO_WAIT);
423 
424     /* Check status.  */
425     if (status != TX_MUTEX_ERROR)
426     {
427 
428         /* Mutex error.  */
429         printf("ERROR #14\n");
430         test_control_return(1);
431     }
432 
433     /* Attempt to put a NULL mutex.  */
434     status =  tx_mutex_put(TX_NULL);
435 
436     /* Check status.  */
437     if (status != TX_MUTEX_ERROR)
438     {
439 
440         /* Mutex error.  */
441         printf("ERROR #15\n");
442         test_control_return(1);
443     }
444 
445     /* Attempt to put a non-created mutex.  */
446     mutex_4.tx_mutex_id =  0;
447     status =  tx_mutex_put(&mutex_4);
448 
449     /* Check status.  */
450     if (status != TX_MUTEX_ERROR)
451     {
452 
453         /* Mutex error.  */
454         printf("ERROR #16\n");
455         test_control_return(1);
456     }
457 #endif
458 
459     /* Attempt to get from mutex that is available.  Should be successful!  */
460     status =  tx_mutex_get(&mutex_0, TX_NO_WAIT);
461 
462     /* Check status.  */
463     if (status != TX_SUCCESS)
464     {
465 
466         /* Mutex error.  */
467         printf("ERROR #17\n");
468         test_control_return(1);
469     }
470 
471     /* Attempt to get the same mutex again.  Should be successful!  */
472     status =  tx_mutex_get(&mutex_0, TX_NO_WAIT);
473 
474     /* Check status.  */
475     if (status != TX_SUCCESS)
476     {
477 
478         /* Mutex error.  */
479         printf("ERROR #18\n");
480         test_control_return(1);
481     }
482 
483     /* Put the mutex. */
484     status =  tx_mutex_put(&mutex_0);
485 
486     /* Check status.  */
487     if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
488     {
489 
490         /* Mutex error.  */
491         printf("ERROR #19\n");
492         test_control_return(1);
493     }
494 
495     /* Put the mutex again.  Should be successful! */
496     status =  tx_mutex_put(&mutex_0);
497 
498     /* Check status.  */
499     if ((status != TX_SUCCESS) != (mutex_0.tx_mutex_owner != TX_NULL))
500     {
501 
502         /* Mutex error.  */
503         printf("ERROR #20\n");
504         test_control_return(1);
505     }
506 
507     /* Relinquish to allow other thread to get the mutex.  */
508     tx_thread_relinquish();
509 
510     /* Attempt to get the mutex.  Should be unsuccessful.  */
511     status =  tx_mutex_get(&mutex_1, TX_NO_WAIT);
512 
513     /* Check status.  */
514     if (status != TX_NOT_AVAILABLE)
515     {
516 
517         /* Mutex error.  */
518         printf("ERROR #21\n");
519         test_control_return(1);
520     }
521 
522     /* Relinquish again so that the other thread can release it.  */
523     tx_thread_relinquish();
524 
525     /* Delete mutex.  */
526     status =  tx_mutex_delete(&mutex_0);
527 
528     /* Check status.  */
529     if (status != TX_SUCCESS)
530     {
531 
532         /* Mutex error.  */
533         printf("ERROR #22\n");
534         test_control_return(1);
535     }
536 
537     status =  tx_mutex_delete(&mutex_1);
538 
539     /* Check status.  */
540     if (status != TX_SUCCESS)
541     {
542 
543         /* Mutex error.  */
544         printf("ERROR #23\n");
545         test_control_return(1);
546     }
547 
548     /* Attempt to get a priority inheritance mutex.  */
549     status =  tx_mutex_get(&mutex_2, TX_NO_WAIT);
550 
551     /* Check status.  */
552     if (status != TX_SUCCESS)
553     {
554 
555         /* Mutex error.  */
556         printf("ERROR #24\n");
557         test_control_return(1);
558     }
559 
560     /* Attempt to get another priority inheritance mutex.  */
561     status =  tx_mutex_get(&mutex_3, TX_NO_WAIT);
562 
563     /* Check status.  */
564     if (status != TX_SUCCESS)
565     {
566 
567         /* Mutex error.  */
568         printf("ERROR #25\n");
569         test_control_return(1);
570     }
571 
572 #ifndef TX_DISABLE_ERROR_CHECKING
573 
574     /* Create a timer for the test.  */
575     tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
576 
577     /* Setup the ISR.  */
578     test_isr_dispatch =  test_isr;
579 
580     /* Sleep for a bit...  */
581     tx_thread_sleep(3);
582 
583     /* Wakeup thread 2 to get the ISR to take place on top of the thread.  */
584     tx_thread_resume(&thread_2);
585 
586     /* Sleep for a bit...  */
587     tx_thread_sleep(3);
588 
589     /* Clear the ISR.  */
590     test_isr_dispatch =  TX_NULL;
591 
592     /* Test for error.  */
593     if ((error) || (timer_executed != 1) || (isr_executed != 1))
594     {
595 
596         /* Block memory error.  */
597         printf("ERROR #26\n");
598         test_control_return(1);
599     }
600 
601 #endif
602 
603     /* Release mutex multiple times.  */
604     status =  tx_mutex_put(&mutex_2);
605     status += tx_mutex_put(&mutex_2);
606 
607     /* Check status.  */
608     if (status != TX_NOT_OWNED)
609     {
610 
611         /* Mutex error.  */
612         printf("ERROR #27\n");
613         test_control_return(1);
614     }
615 
616     /* Attempt to release a mutex that is not owned.  */
617     status =  _tx_mutex_put(&mutex_2);
618 
619     /* Check status.  */
620     if (status != TX_NOT_OWNED)
621     {
622 
623         /* Mutex error.  */
624         printf("ERROR #28\n");
625         test_control_return(1);
626     }
627 
628     /* Delete mutex.  */
629     status =  tx_mutex_delete(&mutex_2);
630 
631     /* Check status.  */
632     if (status != TX_SUCCESS)
633     {
634 
635         /* Mutex error.  */
636         printf("ERROR #29\n");
637         test_control_return(1);
638     }
639 
640     /* Get mutex 8.  */
641     status =  tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
642 
643     /* Start thread 3 and 4.  */
644     status += tx_thread_resume(&thread_3);
645     status += tx_thread_resume(&thread_4);
646 
647     /* Sleep to let thread 3 suspend on the mutex.  */
648     tx_thread_sleep(2);
649 
650     /* Now, put the mutex to give it to thread 3.  */
651     status += tx_mutex_put(&mutex_8);
652 
653     /* Check status.  */
654     if (status != TX_SUCCESS)
655     {
656 
657         /* Mutex error.  */
658         printf("ERROR #29a\n");
659         test_control_return(1);
660     }
661 
662     status =  tx_mutex_delete(&mutex_3);
663 
664     /* Check status.  */
665     if (status != TX_SUCCESS)
666     {
667 
668         /* Mutex error.  */
669         printf("ERROR #30\n");
670         test_control_return(1);
671     }
672     else
673     {
674 
675         /* Successful test.  */
676         printf("SUCCESS!\n");
677         test_control_return(0);
678     }
679 }
680 
thread_1_entry(ULONG thread_input)681 static void    thread_1_entry(ULONG thread_input)
682 {
683 
684 UINT    status;
685 
686     /* Increment thread 1 counter.  */
687     thread_1_counter++;
688 
689     /* Attempt to get from mutex that is available.  Should be successful!  */
690     status =  tx_mutex_get(&mutex_1, TX_NO_WAIT);
691 
692     /* Check status.  */
693     if (status != TX_SUCCESS)
694     {
695 
696         /* Mutex error.  */
697         printf("ERROR #31\n");
698         test_control_return(1);
699     }
700 
701     /* Let other thread run again.  */
702     tx_thread_relinquish();
703 
704     /* Release mutex!  */
705     status =  tx_mutex_put(&mutex_1);
706 
707     /* Check status.  */
708     if (status != TX_SUCCESS)
709     {
710 
711         /* Mutex error.  */
712         printf("ERROR #32\n");
713         test_control_return(1);
714     }
715 
716     /* Create and obtain a couple mutexes so the thread completion can release them.  */
717     status =  tx_mutex_create(&mutex_6, "mutex 6", TX_NO_INHERIT);
718     status += tx_mutex_create(&mutex_7, "mutex 7", TX_NO_INHERIT);
719     status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
720     status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
721     status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
722     status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
723 
724     /* Check status.  */
725     if (status != TX_SUCCESS)
726     {
727 
728         /* Mutex error.  */
729         printf("ERROR #33\n");
730         test_control_return(1);
731     }
732 }
733 
734 
thread_2_entry(ULONG thread_input)735 static void    thread_2_entry(ULONG thread_input)
736 {
737 
738     while(1)
739     {
740 
741         tx_thread_relinquish();
742     }
743 }
744 
745 
thread_3_entry(ULONG thread_input)746 static void    thread_3_entry(ULONG thread_input)
747 {
748 
749     while(1)
750     {
751 
752         tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
753         tx_mutex_put(&mutex_8);
754     }
755 }
756 
757 
thread_4_entry(ULONG thread_input)758 static void    thread_4_entry(ULONG thread_input)
759 {
760 
761     while(1)
762     {
763 
764         tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
765         tx_mutex_put(&mutex_8);
766     }
767 }
768