cf927d0f6801cdee0d3bf9a28b46a3b020662db2
[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  * $test$: cp bertos/cfg/cfg_proc.h $cfgdir/
40  * $test$: echo  "#undef CONFIG_KERN" >> $cfgdir/cfg_proc.h
41  * $test$: echo "#define CONFIG_KERN 1" >> $cfgdir/cfg_proc.h
42  * $test$: cp bertos/cfg/cfg_sem.h $cfgdir/
43  * $test$: echo  "#undef CONFIG_KERN_SEMAPHORES" >> $cfgdir/cfg_sem.h
44  * $test$: echo "#define CONFIG_KERN_SEMAPHORES 1" >> $cfgdir/cfg_sem.h
45  */
46
47 #include <cfg/debug.h>
48 #include <cfg/test.h>
49
50 #include <kern/sem.h>
51 #include <kern/proc.h>
52 #include <kern/irq.h>
53
54 #include <drv/timer.h>
55
56 // Global settings for the test.
57 #define MAX_GLOBAL_COUNT             1024
58 #define TEST_TIME_OUT_MS             6000
59 #define DELAY                           5
60
61 // Settings for the test process.
62 //Process 1
63 #define INC_PROC_T1                     1
64 #define DELAY_PROC_T1   INC_PROC_T1*DELAY
65 //Process 2
66 #define INC_PROC_T2                     3
67 #define DELAY_PROC_T2   INC_PROC_T2*DELAY
68 //Process 3
69 #define INC_PROC_T3                     5
70 #define DELAY_PROC_T3   INC_PROC_T3*DELAY
71 //Process 4
72 #define INC_PROC_T4                     7
73 #define DELAY_PROC_T4   INC_PROC_T4*DELAY
74 //Process 5
75 #define INC_PROC_T5                    11
76 #define DELAY_PROC_T5   INC_PROC_T5*DELAY
77 //Process 6
78 #define INC_PROC_T6                    13
79 #define DELAY_PROC_T6   INC_PROC_T6*DELAY
80 //Process 7
81 #define INC_PROC_T7                    17
82 #define DELAY_PROC_T7   INC_PROC_T7*DELAY
83 //Process 8
84 #define INC_PROC_T8                    19
85 #define DELAY_PROC_T8   INC_PROC_T8*DELAY
86
87 Semaphore sem;
88 unsigned int global_count = 0;
89
90 /*
91  * These macros generate the code needed to create the test process functions.
92  */
93 #define PROC_TEST(num) static void proc_semTest##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)  PROC_DEFINE_STACK(proc_sem_test##num##_stack, KERN_MINSTACKSIZE * 2)
113 #define PROC_TEST_INIT(num)   proc_new(proc_semTest##num, NULL, sizeof(proc_sem_test##num##_stack), proc_sem_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 // Define process stacks for test.
126 PROC_TEST_STACK(1)
127 PROC_TEST_STACK(2)
128 PROC_TEST_STACK(3)
129 PROC_TEST_STACK(4)
130 PROC_TEST_STACK(5)
131 PROC_TEST_STACK(6)
132 PROC_TEST_STACK(7)
133 PROC_TEST_STACK(8)
134
135 /**
136  * Run semaphore test
137  */
138 int sem_testRun(void)
139 {
140         ticks_t start_time = timer_clock();
141
142         kprintf("Run semaphore test..\n");
143
144         //Init the process tests
145         PROC_TEST_INIT(1)
146         PROC_TEST_INIT(2)
147         PROC_TEST_INIT(3)
148         PROC_TEST_INIT(4)
149         PROC_TEST_INIT(5)
150         PROC_TEST_INIT(6)
151         PROC_TEST_INIT(7)
152         PROC_TEST_INIT(8)
153         kputs("> Main: Processes created\n");
154
155         /*
156          * Wait until all processes exit, if something goes wrong we return an
157          * error after timeout_ms.
158          */
159         while((timer_clock() - start_time) < ms_to_ticks(TEST_TIME_OUT_MS))
160         {
161                 if (sem_attempt(&sem))
162                 {
163                         kputs("> Main: Check if test has finished..\n");
164                         if(global_count == MAX_GLOBAL_COUNT)
165                         {
166                                 kputs("> Main: Test Finished..Ok!\n");
167                                 return 0;
168                         }
169                         sem_release(&sem);
170                         kputs("> Main: Test is still running..\n");
171                 }
172                 proc_yield();
173         }
174
175         kputs("Semaphore Test fail..\n");
176         return -1;
177 }
178
179 int sem_testSetup(void)
180 {
181         kdbg_init();
182
183         kprintf("Init Semaphore..");
184         sem_init(&sem);
185         kprintf("Done.\n");
186
187         #if CONFIG_KERN_PREEMPT
188                 kprintf("Init Interrupt (preempt mode)..");
189                 irq_init();
190                 kprintf("Done.\n");
191         #endif
192
193         kprintf("Init Timer..");
194         timer_init();
195         kprintf("Done.\n");
196
197         kprintf("Init Process..");
198         proc_init();
199         kprintf("Done.\n");
200
201         return 0;
202 }
203
204 int sem_testTearDown(void)
205 {
206         kputs("TearDown Semaphore test.\n");
207         return 0;
208 }
209
210 TEST_MAIN(sem);