1 //==========================================================================
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.
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.
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
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.
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.
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.
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####
44 // Contributors: nickg
46 // Description: Tests POSIX signal functionality.
48 //####DESCRIPTIONEND####
49 //==========================================================================
51 #include <cyg/infra/testcase.h>
52 #include <pkgconf/posix.h>
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 #elif !defined(CYGPKG_POSIX_SEMAPHORES)
59 #define NA_MSG "POSIX semaphores not enabled"
71 #include <sys/types.h>
74 #include <semaphore.h>
77 //--------------------------------------------------------------------------
80 char thread1_stack[PTHREAD_STACK_MIN*2];
81 char thread2_stack[PTHREAD_STACK_MIN*2];
83 //--------------------------------------------------------------------------
96 volatile int sigusr1_called = 0;
97 volatile int sigusr2_called = 0;
99 //--------------------------------------------------------------------------
100 // Signal handler functions
102 static void sigusr1( int signo, siginfo_t *info, void *context )
104 CYG_TEST_INFO( "sigusr1() handler called" );
105 CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
106 CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
107 CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
108 CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF01, "Siginfo value wrong");
109 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
114 static void sigusr2( int signo, siginfo_t *info, void *context )
116 CYG_TEST_INFO( "sigusr2() handler called" );
117 CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
118 CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
119 CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
120 CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF02, "Siginfo value wrong");
121 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread2), "Not called in thread2");
126 //--------------------------------------------------------------------------
128 void *pthread_entry1( void *arg)
133 CYG_TEST_INFO( "Thread 1 running" );
138 // remove USR1 signal
139 sigdelset( &mask, SIGUSR1 );
142 pthread_sigmask( SIG_SETMASK, &mask, NULL );
144 // Get main thread going again
147 while( sigusr1_called < 1 )
149 CYG_TEST_INFO( "Thread1: calling pause()");
153 CYG_TEST_INFO( "Thread1: calling pthread_exit()");
157 //--------------------------------------------------------------------------
159 void *pthread_entry2( void *arg)
163 CYG_TEST_INFO( "Thread 2 running" );
168 // remove USR2 signal
169 sigdelset( &mask, SIGUSR2 );
172 pthread_sigmask( SIG_SETMASK, &mask, NULL );
174 // Get main thread going again
177 while( sigusr2_called < 6 )
179 CYG_TEST_INFO( "Thread2: calling pause()");
183 CYG_TEST_INFO( "Thread2: calling pthread_exit()");
187 //--------------------------------------------------------------------------
189 int main(int argc, char **argv)
198 // Make a full signal set
202 // Install signal handlers
206 sa.sa_sigaction = sigusr1;
208 sa.sa_flags = SA_SIGINFO;
210 ret = sigaction( SIGUSR1, &sa, NULL );
212 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
217 sa.sa_sigaction = sigusr2;
219 sa.sa_flags = SA_SIGINFO;
221 ret = sigaction( SIGUSR2, &sa, NULL );
223 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
231 struct itimerspec value;
233 sev.sigev_notify = SIGEV_SIGNAL;
234 sev.sigev_signo = SIGUSR1;
235 sev.sigev_value.sival_int = 0xABCDEF01;
237 value.it_value.tv_sec = 1;
238 value.it_value.tv_nsec = 0;
239 value.it_interval.tv_sec = 0;
240 value.it_interval.tv_nsec = 0;
242 ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );
244 CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
246 ret = timer_settime( timer1, 0, &value, NULL );
248 CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
254 struct itimerspec value;
256 sev.sigev_notify = SIGEV_SIGNAL;
257 sev.sigev_signo = SIGUSR2;
258 sev.sigev_value.sival_int = 0xABCDEF02;
260 value.it_value.tv_sec = 0;
261 value.it_value.tv_nsec = 500000000;
262 value.it_interval.tv_sec = 0;
263 value.it_interval.tv_nsec = 250000000;
265 ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );
267 CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
269 ret = timer_settime( timer2, 0, &value, NULL );
271 CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
276 pthread_sigmask( SIG_SETMASK, &mask, NULL );
278 sem_init( &sem, 0, 0 );
280 // Create test threads
283 pthread_attr_init( &attr );
285 pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
286 pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );
288 pthread_create( &thread1,
295 pthread_attr_init( &attr );
297 pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
298 pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );
300 pthread_create( &thread2,
306 // Wait for other thread to get started
307 CYG_TEST_INFO( "Main: calling sem_wait()");
309 CYG_TEST_INFO( "Main: calling sem_wait() again");
312 // Now join with thread1
313 CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
314 pthread_join( thread1, &retval );
316 CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
319 CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
320 pthread_join( thread2, &retval );
322 // now delete the timers
323 CYG_TEST_INFO( "Main: calling timer_delete(timer1)");
324 ret = timer_delete( timer1 );
326 CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");
328 CYG_TEST_INFO( "Main: calling timer_delete(timer2)");
329 ret = timer_delete( timer2 );
331 CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");
334 CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
336 CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
337 CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );
339 CYG_TEST_PASS_FINISH( "timer1" );
344 //--------------------------------------------------------------------------