]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/compat/posix/v2_0/tests/timer1.c
Initial revision
[karo-tx-redboot.git] / packages / compat / posix / v2_0 / tests / timer1.c
1 //==========================================================================
2 //
3 //        timer1.cxx
4 //
5 //        POSIX signal test 1
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):     nickg
44 // Contributors:  nickg
45 // Date:          2000-04-10
46 // Description:   Tests POSIX signal functionality.
47 //
48 //####DESCRIPTIONEND####
49 //==========================================================================
50
51 #include <cyg/infra/testcase.h>
52 #include <pkgconf/posix.h>
53
54 #ifndef CYGPKG_POSIX_SIGNALS
55 #define NA_MSG "No POSIX signals"
56 #elif !defined(CYGPKG_POSIX_TIMERS)
57 #define NA_MSG "No POSIX timers"
58 #endif
59
60 #ifdef NA_MSG
61 void
62 cyg_start(void)
63 {
64     CYG_TEST_INIT();
65     CYG_TEST_NA(NA_MSG);
66 }
67 #else
68
69 #include <sys/types.h>
70 #include <pthread.h>
71 #include <signal.h>
72 #include <semaphore.h>
73 #include <time.h>
74
75 //--------------------------------------------------------------------------
76 // Thread stack.
77
78 char thread1_stack[PTHREAD_STACK_MIN*2];
79 char thread2_stack[PTHREAD_STACK_MIN*2];
80
81 //--------------------------------------------------------------------------
82 // Local variables
83
84 // Sync semaphore
85 sem_t sem;
86
87 // Thread IDs
88 pthread_t thread1;
89 pthread_t thread2;
90
91 timer_t timer1;
92 timer_t timer2;
93
94 volatile int sigusr1_called = 0;
95 volatile int sigusr2_called = 0;
96
97 //--------------------------------------------------------------------------
98 // Signal handler functions
99
100 static void sigusr1( int signo, siginfo_t *info, void *context )
101 {
102     CYG_TEST_INFO( "sigusr1() handler called" );
103     CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
104     CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
105     CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
106     CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF01, "Siginfo value wrong");
107     CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
108
109     sigusr1_called++;
110 }
111
112 static void sigusr2( int signo, siginfo_t *info, void *context )
113 {
114     CYG_TEST_INFO( "sigusr2() handler called" );
115     CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
116     CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
117     CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
118     CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF02, "Siginfo value wrong");
119     CYG_TEST_CHECK( pthread_equal(pthread_self(), thread2), "Not called in thread2");
120
121     sigusr2_called++;
122 }
123
124 //--------------------------------------------------------------------------
125
126 void *pthread_entry1( void *arg)
127 {
128     sigset_t mask;
129
130     
131     CYG_TEST_INFO( "Thread 1 running" );
132
133     // Make a full set
134     sigfillset( &mask );
135
136     // remove USR1 signal
137     sigdelset( &mask, SIGUSR1 );
138
139     // Set signal mask
140     pthread_sigmask( SIG_SETMASK, &mask, NULL );
141     
142     // Get main thread going again
143     sem_post( &sem );
144
145     while( sigusr1_called < 1 )
146     {
147         CYG_TEST_INFO( "Thread1: calling pause()");        
148         pause();
149     }
150
151     CYG_TEST_INFO( "Thread1: calling pthread_exit()");    
152     pthread_exit( arg );
153 }
154
155 //--------------------------------------------------------------------------
156
157 void *pthread_entry2( void *arg)
158 {
159     sigset_t mask;
160     
161     CYG_TEST_INFO( "Thread 2 running" );
162
163     // Make a full set
164     sigfillset( &mask );
165
166     // remove USR2 signal
167     sigdelset( &mask, SIGUSR2 );
168
169     // Set signal mask
170     pthread_sigmask( SIG_SETMASK, &mask, NULL );
171     
172     // Get main thread going again
173     sem_post( &sem );
174
175     while( sigusr2_called < 6 )
176     {
177         CYG_TEST_INFO( "Thread2: calling pause()");        
178         pause();
179     }
180
181     CYG_TEST_INFO( "Thread2: calling pthread_exit()");    
182     pthread_exit( arg );
183 }
184
185 //--------------------------------------------------------------------------
186
187 int main(int argc, char **argv)
188 {
189     int ret;
190     sigset_t mask;
191     pthread_attr_t attr;
192     void *retval;
193     
194     CYG_TEST_INIT();
195
196     // Make a full signal set
197     sigfillset( &mask );
198
199     
200     // Install signal handlers
201     {
202         struct sigaction sa;
203
204         sa.sa_sigaction = sigusr1;
205         sa.sa_mask = mask;
206         sa.sa_flags = SA_SIGINFO;
207
208         ret = sigaction( SIGUSR1, &sa, NULL );
209
210         CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
211     }
212     {
213         struct sigaction sa;
214
215         sa.sa_sigaction = sigusr2;
216         sa.sa_mask = mask;
217         sa.sa_flags = SA_SIGINFO;
218
219         ret = sigaction( SIGUSR2, &sa, NULL );
220
221         CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
222     }
223
224
225     // Create the timers
226
227     {
228         struct sigevent sev;
229         struct itimerspec value;
230         
231         sev.sigev_notify                = SIGEV_SIGNAL;
232         sev.sigev_signo                 = SIGUSR1;
233         sev.sigev_value.sival_int       = 0xABCDEF01;
234
235         value.it_value.tv_sec           = 1;
236         value.it_value.tv_nsec          = 0;
237         value.it_interval.tv_sec        = 0;
238         value.it_interval.tv_nsec       = 0;
239         
240         ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );
241
242         CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
243
244         ret = timer_settime( timer1, 0, &value, NULL );
245
246         CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
247     }
248
249 #if 1    
250     {
251         struct sigevent sev;
252         struct itimerspec value;
253         
254         sev.sigev_notify                = SIGEV_SIGNAL;
255         sev.sigev_signo                 = SIGUSR2;
256         sev.sigev_value.sival_int       = 0xABCDEF02;
257
258         value.it_value.tv_sec           = 0;
259         value.it_value.tv_nsec          = 500000000;
260         value.it_interval.tv_sec        = 0;
261         value.it_interval.tv_nsec       = 250000000;
262         
263         ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );
264
265         CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
266
267         ret = timer_settime( timer2, 0, &value, NULL );
268
269         CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
270     }
271 #endif    
272     
273     // Mask all signals
274     pthread_sigmask( SIG_SETMASK, &mask, NULL );
275     
276     sem_init( &sem, 0, 0 );
277     
278     // Create test threads
279
280     {
281         pthread_attr_init( &attr );
282
283         pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
284         pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );
285
286         pthread_create( &thread1,
287                         &attr,
288                         pthread_entry1,
289                         (void *)0x12345671);
290     }
291
292     {
293         pthread_attr_init( &attr );
294
295         pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
296         pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );
297
298         pthread_create( &thread2,
299                         &attr,
300                         pthread_entry2,
301                         (void *)0x12345672);
302     }
303     
304     // Wait for other thread to get started
305     CYG_TEST_INFO( "Main: calling sem_wait()");
306     sem_wait( &sem );
307     CYG_TEST_INFO( "Main: calling sem_wait() again");    
308     sem_wait( &sem );
309
310     // Now join with thread1
311     CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
312     pthread_join( thread1, &retval );
313
314     CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
315     
316     // And thread 2
317     CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
318     pthread_join( thread2, &retval );
319
320     // now delete the timers
321     CYG_TEST_INFO( "Main: calling timer_delete(timer1)");    
322     ret = timer_delete( timer1 );
323
324     CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");
325
326     CYG_TEST_INFO( "Main: calling timer_delete(timer2)");    
327     ret = timer_delete( timer2 );
328
329     CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");
330
331     
332     CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
333     
334     CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
335     CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );
336
337     CYG_TEST_PASS_FINISH( "timer1" );
338 }
339
340 #endif
341
342 //--------------------------------------------------------------------------
343 // end of timer1.c