Use macros to generate a multiple test code for semaphore.
[bertos.git] / bertos / kern / sem_test.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
30  * -->
31  *
32  * \brief Semaphore test.
33  *
34  * \version $Id$
35  * 
36  * \author Daniele Basile <asterix@develer.com>
37  * \author Stefano Fedrigo <aleph@develer.com> 
38  * 
39  */
40
41 #include <cfg/test.h>
42
43 #include <kern/sem.h>
44 #include <kern/proc.h>
45 #include <kern/irq.h>
46
47 #include <drv/timer.h>
48
49 // Global settings for the test.
50 #define MAX_GLOBAL_COUNT             1024
51 #define TEST_TIME_OUT_MS             4000
52 #define DELAY                          10
53
54 // Settings for the test process.
55 //Process 1
56 #define INC_PROC_T1                     1
57 #define DELAY_PROC_T1   INC_PROC_T1*DELAY
58 //Process 2
59 #define INC_PROC_T2                     3
60 #define DELAY_PROC_T2   INC_PROC_T2*DELAY
61 //Process 3
62 #define INC_PROC_T3                     5
63 #define DELAY_PROC_T3   INC_PROC_T3*DELAY
64 //Process 4
65 #define INC_PROC_T4                     7
66 #define DELAY_PROC_T4   INC_PROC_T3*DELAY
67 //Process 5
68 #define INC_PROC_T5                    11
69 #define DELAY_PROC_T5   INC_PROC_T3*DELAY
70 //Process 6
71 #define INC_PROC_T6                    13
72 #define DELAY_PROC_T6   INC_PROC_T3*DELAY
73 //Process 7
74 #define INC_PROC_T7                    17
75 #define DELAY_PROC_T7   INC_PROC_T3*DELAY
76 //Process 8
77 #define INC_PROC_T8                    19
78 #define DELAY_PROC_T8   INC_PROC_T3*DELAY
79 //Process 9
80 #define INC_PROC_T9                    23
81 #define DELAY_PROC_T9   INC_PROC_T3*DELAY
82 //Process 10
83 #define INC_PROC_T10                   29
84 #define DELAY_PROC_T10  INC_PROC_T3*DELAY
85
86 Semaphore sem;
87 unsigned int global_count = 0;
88
89 /*
90  * These macro generate the code that needed to create the
91  * test process function and all it needed. 
92  */ 
93 #define PROC_TEST(num) static void proc_test##num(void) \
94 { \
95         unsigned int local_count = 0; \
96         \
97         for (int i = 0; i < INC_PROC_T##num; ++i) \
98         { \
99                 sem_obtain(&sem); \
100                 kprintf("> test%d: Obtain semaphore.\n", num); \
101                 local_count = global_count; \
102                 kprintf("> test%d: Read global count [%d]\n", num, local_count); \
103                 timer_delay(DELAY_PROC_T##num); \
104                 local_count += INC_PROC_T##num; \
105                 global_count = local_count; \
106                 kprintf("> test%d: Update count g[%d] l[%d]\n", num, global_count, local_count); \
107                 sem_release(&sem); \
108                 kprintf("> test%d: Relase semaphore.\n", num); \
109         } \
110 } \
111
112 #define PROC_TEST_STACK(num)  static cpu_stack_t proc_test##num##_stack[CONFIG_KERN_MINSTACKSIZE / sizeof(cpu_stack_t)];
113 #define PROC_TEST_INIT(num)   proc_new(proc_test##num, NULL, sizeof(proc_test##num##_stack), proc_test##num##_stack);
114
115 // Define process
116 PROC_TEST(1)
117 PROC_TEST(2)
118 PROC_TEST(3)
119 PROC_TEST(4)
120 PROC_TEST(5)
121 PROC_TEST(6)
122 PROC_TEST(7)
123 PROC_TEST(8)
124 /*
125 PROC_TEST(9)
126 PROC_TEST(10)
127 */
128 // Define process stacks for test.
129 PROC_TEST_STACK(1)
130 PROC_TEST_STACK(2)
131 PROC_TEST_STACK(3)
132 PROC_TEST_STACK(4)
133 PROC_TEST_STACK(5)
134 PROC_TEST_STACK(6)
135 PROC_TEST_STACK(7)
136 PROC_TEST_STACK(8)
137 /*
138 PROC_TEST_STACK(9)
139 PROC_TEST_STACK(10)
140 */
141 /**
142  * Run semaphore test
143  */
144 int sem_testRun(void)
145 {
146         ticks_t start_time = timer_clock();
147
148         kprintf("Run semaphore test..\n");
149         
150         //Init the process tests
151         PROC_TEST_INIT(1)
152         PROC_TEST_INIT(2)
153         PROC_TEST_INIT(3)
154         PROC_TEST_INIT(4)
155         PROC_TEST_INIT(5)
156         PROC_TEST_INIT(6)
157         PROC_TEST_INIT(7)
158         PROC_TEST_INIT(8)
159         /*
160         PROC_TEST_INIT(9)
161         PROC_TEST_INIT(10)
162          */
163         kputs("> Main: Processes created\n");
164         
165         /*
166          * Wait until all process finishing, if some going wrong we return 
167          * error after time_out_ms ms.
168          */ 
169         while((timer_clock() - start_time) < ms_to_ticks(TEST_TIME_OUT_MS))
170         {
171                 if (sem_attempt(&sem))
172                 {
173                         kputs("> Main: Check if test is finish..\n");
174                         if(global_count == MAX_GLOBAL_COUNT)
175                         {
176                                 kputs("> Main: Test Finished..Ok!\n");
177                                 return 0;
178                         }
179                         sem_release(&sem);
180                         kputs("> Main: Test is still running..\n");
181                 }
182                 proc_yield();
183         }
184         
185         kputs("Semaphore Test fail..\n");
186         return -1;
187 }
188
189 int sem_testSetup(void)
190 {
191         kdbg_init();
192
193         kprintf("Init Semaphore..");
194         sem_init(&sem);
195         kprintf("Done.\n");
196         
197         #if CONFIG_KERN_PREEMPT
198                 kprintf("Init Interrupt (preempt mode)..");
199                 irq_init();
200                 kprintf("Done.\n");
201         #endif
202
203         kprintf("Init Timer..");
204         timer_init();
205         kprintf("Done.\n");
206         
207         kprintf("Init Process..");
208         proc_init();
209         kprintf("Done.\n");
210         
211         return 0;
212 }
213
214 int sem_testTearDown(void)
215 {
216         kputs("TearDown Semaphore test.\n");
217         return 0;
218 }
219
220 TEST_MAIN(sem);