1045205df9fc0bd5828124f6d429f6534c05a99f
[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  *
35  * \author Daniele Basile <asterix@develer.com>
36  * \author Stefano Fedrigo <aleph@develer.com>
37  *
38  * $test$: cp bertos/cfg/cfg_proc.h $cfgdir/
39  * $test$: echo  "#undef CONFIG_KERN" >> $cfgdir/cfg_proc.h
40  * $test$: echo "#define CONFIG_KERN 1" >> $cfgdir/cfg_proc.h
41  * $test$: cp bertos/cfg/cfg_sem.h $cfgdir/
42  * $test$: echo  "#undef CONFIG_KERN_SEMAPHORES" >> $cfgdir/cfg_sem.h
43  * $test$: echo "#define CONFIG_KERN_SEMAPHORES 1" >> $cfgdir/cfg_sem.h
44  */
45
46 #include <cfg/debug.h>
47 #include <cfg/test.h>
48
49 #include <kern/sem.h>
50 #include <kern/proc.h>
51 #include <kern/irq.h>
52
53 #include <drv/timer.h>
54
55 // Global settings for the test.
56 #define MAX_GLOBAL_COUNT             1024
57 #define TEST_TIME_OUT_MS             6000
58 #define DELAY                           5
59
60 // Settings for the test process.
61 //Process 1
62 #define INC_PROC_T1                     1
63 #define DELAY_PROC_T1   INC_PROC_T1*DELAY
64 //Process 2
65 #define INC_PROC_T2                     3
66 #define DELAY_PROC_T2   INC_PROC_T2*DELAY
67 //Process 3
68 #define INC_PROC_T3                     5
69 #define DELAY_PROC_T3   INC_PROC_T3*DELAY
70 //Process 4
71 #define INC_PROC_T4                     7
72 #define DELAY_PROC_T4   INC_PROC_T4*DELAY
73 //Process 5
74 #define INC_PROC_T5                    11
75 #define DELAY_PROC_T5   INC_PROC_T5*DELAY
76 //Process 6
77 #define INC_PROC_T6                    13
78 #define DELAY_PROC_T6   INC_PROC_T6*DELAY
79 //Process 7
80 #define INC_PROC_T7                    17
81 #define DELAY_PROC_T7   INC_PROC_T7*DELAY
82 //Process 8
83 #define INC_PROC_T8                    19
84 #define DELAY_PROC_T8   INC_PROC_T8*DELAY
85
86 Semaphore sem;
87 unsigned int global_count = 0;
88
89 /*
90  * These macros generate the code needed to create the test process functions.
91  */
92 #define PROC_TEST(num) static void proc_semTest##num(void) \
93 { \
94         unsigned int local_count = 0; \
95         \
96         for (int i = 0; i < INC_PROC_T##num; ++i) \
97         { \
98                 sem_obtain(&sem); \
99                 kprintf("> test%d: Obtain semaphore.\n", num); \
100                 local_count = global_count; \
101                 kprintf("> test%d: Read global count [%d]\n", num, local_count); \
102                 timer_delay(DELAY_PROC_T##num); \
103                 local_count += INC_PROC_T##num; \
104                 global_count = local_count; \
105                 kprintf("> test%d: Update count g[%d] l[%d]\n", num, global_count, local_count); \
106                 sem_release(&sem); \
107                 kprintf("> test%d: Relase semaphore.\n", num); \
108         } \
109 } \
110
111 #define PROC_TEST_STACK(num)  PROC_DEFINE_STACK(proc_sem_test##num##_stack, KERN_MINSTACKSIZE * 2)
112 #define PROC_TEST_INIT(num)   proc_new(proc_semTest##num, NULL, sizeof(proc_sem_test##num##_stack), proc_sem_test##num##_stack);
113
114 // Define process
115 PROC_TEST(1)
116 PROC_TEST(2)
117 PROC_TEST(3)
118 PROC_TEST(4)
119 PROC_TEST(5)
120 PROC_TEST(6)
121 PROC_TEST(7)
122 PROC_TEST(8)
123
124 // Define process stacks for test.
125 PROC_TEST_STACK(1)
126 PROC_TEST_STACK(2)
127 PROC_TEST_STACK(3)
128 PROC_TEST_STACK(4)
129 PROC_TEST_STACK(5)
130 PROC_TEST_STACK(6)
131 PROC_TEST_STACK(7)
132 PROC_TEST_STACK(8)
133
134 /**
135  * Run semaphore test
136  */
137 int sem_testRun(void)
138 {
139         ticks_t start_time = timer_clock();
140
141         kprintf("Run semaphore test..\n");
142
143         //Init the process tests
144         PROC_TEST_INIT(1)
145         PROC_TEST_INIT(2)
146         PROC_TEST_INIT(3)
147         PROC_TEST_INIT(4)
148         PROC_TEST_INIT(5)
149         PROC_TEST_INIT(6)
150         PROC_TEST_INIT(7)
151         PROC_TEST_INIT(8)
152         kputs("> Main: Processes created\n");
153
154         /*
155          * Wait until all processes exit, if something goes wrong we return an
156          * error after timeout_ms.
157          */
158         while((timer_clock() - start_time) < ms_to_ticks(TEST_TIME_OUT_MS))
159         {
160                 if (sem_attempt(&sem))
161                 {
162                         kputs("> Main: Check if test has finished..\n");
163                         if(global_count == MAX_GLOBAL_COUNT)
164                         {
165                                 kputs("> Main: Test Finished..Ok!\n");
166                                 return 0;
167                         }
168                         sem_release(&sem);
169                         kputs("> Main: Test is still running..\n");
170                 }
171                 proc_yield();
172         }
173
174         kputs("Semaphore Test fail..\n");
175         return -1;
176 }
177
178 int sem_testSetup(void)
179 {
180         kdbg_init();
181
182         kprintf("Init Semaphore..");
183         sem_init(&sem);
184         kprintf("Done.\n");
185
186         kprintf("Init Timer..");
187         timer_init();
188         kprintf("Done.\n");
189
190         kprintf("Init Process..");
191         proc_init();
192         kprintf("Done.\n");
193
194         return 0;
195 }
196
197 int sem_testTearDown(void)
198 {
199         kputs("TearDown Semaphore test.\n");
200         return 0;
201 }
202
203 TEST_MAIN(sem);