1 //==========================================================================
5 // POSIX sigsetjmp test
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 sigsetjmp functionality.
48 //####DESCRIPTIONEND####
49 //==========================================================================
51 #include <cyg/infra/testcase.h>
52 #include <pkgconf/posix.h>
54 #if !defined(CYGPKG_POSIX_SIGNALS)
55 #define NA_MSG "POSIX signals not enabled"
56 #elif !defined(CYGPKG_POSIX_PTHREAD)
57 #define NA_MSG "POSIX threads not enabled"
58 #elif !defined(CYGPKG_POSIX_SEMAPHORES)
59 #define NA_MSG "POSIX semaphores not enabled"
71 #include <sys/types.h>
74 #include <semaphore.h>
78 #include <cyg/infra/testcase.h>
80 //--------------------------------------------------------------------------
83 char thread1_stack[PTHREAD_STACK_MIN*2];
84 char thread2_stack[PTHREAD_STACK_MIN*2];
86 //--------------------------------------------------------------------------
99 volatile int sigusr1_called = 0;
100 volatile int sigusr2_called = 0;
105 //--------------------------------------------------------------------------
106 // Signal handler functions
108 static void sigusr1( int signo, siginfo_t *info, void *context )
110 CYG_TEST_INFO( "sigusr1() handler called" );
111 CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
112 CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
113 CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
114 CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF01, "Siginfo value wrong");
115 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
119 CYG_TEST_INFO( "sigusr1() handler calling siglongjmp()" );
121 siglongjmp( jmpbuf1, sigusr1_called );
124 static void sigusr2( int signo, siginfo_t *info, void *context )
126 CYG_TEST_INFO( "sigusr2() handler called" );
127 CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
128 CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
129 CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
130 CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF02, "Siginfo value wrong");
131 CYG_TEST_CHECK( pthread_equal(pthread_self(), thread2), "Not called in thread2");
135 CYG_TEST_INFO( "sigusr2() handler calling siglongjmp()" );
136 siglongjmp( jmpbuf2, sigusr2_called );
139 //--------------------------------------------------------------------------
141 void *pthread_entry1( void *arg)
146 CYG_TEST_INFO( "Thread 1 running" );
151 // remove USR1 signal
152 sigdelset( &mask, SIGUSR1 );
155 pthread_sigmask( SIG_SETMASK, &mask, NULL );
157 // Get main thread going again
164 CYG_TEST_INFO( "Thread1: calling sigsetjmp()");
165 if( sigsetjmp( jmpbuf1, 1 ) != 0 )
166 CYG_TEST_INFO( "Thread1: sigsetjmp() returned non-zero");
168 pthread_sigmask( SIG_SETMASK, NULL, &curmask );
169 CYG_TEST_CHECK( curmask == mask, "Thread1: Signal masks not equal" );
171 if ( sigusr1_called >= 1 )
174 CYG_TEST_INFO( "Thread1: calling pause()");
177 CYG_TEST_INFO( "Thread1: pause() returned");
180 CYG_TEST_INFO( "Thread1: calling pthread_exit()");
184 //--------------------------------------------------------------------------
186 void *pthread_entry2( void *arg)
190 CYG_TEST_INFO( "Thread 2 running" );
195 // remove USR2 signal
196 sigdelset( &mask, SIGUSR2 );
199 pthread_sigmask( SIG_SETMASK, &mask, NULL );
201 // Get main thread going again
208 CYG_TEST_INFO( "Thread2: calling sigsetjmp()");
209 if( sigsetjmp( jmpbuf2, 1 ) != 0 )
210 CYG_TEST_INFO( "Thread2: sigsetjmp() returned non-zero");
212 pthread_sigmask( SIG_SETMASK, NULL, &curmask );
213 CYG_TEST_CHECK( curmask == mask, "Thread2: Signal masks not equal" );
215 if ( sigusr2_called >= 6 )
218 CYG_TEST_INFO( "Thread2: calling pause()");
221 CYG_TEST_INFO( "Thread2: pause() returned");
224 CYG_TEST_INFO( "Thread2: calling pthread_exit()");
228 //--------------------------------------------------------------------------
230 int main(int argc, char **argv)
239 // Make a full signal set
243 // Install signal handlers
247 sa.sa_sigaction = sigusr1;
249 sa.sa_flags = SA_SIGINFO;
251 ret = sigaction( SIGUSR1, &sa, NULL );
253 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
258 sa.sa_sigaction = sigusr2;
260 sa.sa_flags = SA_SIGINFO;
262 ret = sigaction( SIGUSR2, &sa, NULL );
264 CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
272 struct itimerspec value;
274 sev.sigev_notify = SIGEV_SIGNAL;
275 sev.sigev_signo = SIGUSR1;
276 sev.sigev_value.sival_int = 0xABCDEF01;
278 value.it_value.tv_sec = 1;
279 value.it_value.tv_nsec = 0;
280 value.it_interval.tv_sec = 0;
281 value.it_interval.tv_nsec = 0;
283 ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );
285 CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
287 ret = timer_settime( timer1, 0, &value, NULL );
289 CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
294 struct itimerspec value;
296 sev.sigev_notify = SIGEV_SIGNAL;
297 sev.sigev_signo = SIGUSR2;
298 sev.sigev_value.sival_int = 0xABCDEF02;
300 value.it_value.tv_sec = 0;
301 value.it_value.tv_nsec = 500000000;
302 value.it_interval.tv_sec = 0;
303 value.it_interval.tv_nsec = 250000000;
305 ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );
307 CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
309 ret = timer_settime( timer2, 0, &value, NULL );
311 CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
316 pthread_sigmask( SIG_SETMASK, &mask, NULL );
318 sem_init( &sem, 0, 0 );
320 // Create test threads
323 pthread_attr_init( &attr );
325 pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
326 pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );
328 pthread_create( &thread1,
335 pthread_attr_init( &attr );
337 pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
338 pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );
340 pthread_create( &thread2,
346 // Wait for other thread to get started
347 CYG_TEST_INFO( "Main: calling sem_wait()");
349 CYG_TEST_INFO( "Main: calling sem_wait() again");
352 // Now join with thread1
353 CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
354 pthread_join( thread1, &retval );
356 CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
359 CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
360 pthread_join( thread2, &retval );
362 // now delete the timers
363 CYG_TEST_INFO( "Main: calling timer_delete(timer1)");
364 ret = timer_delete( timer1 );
366 CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");
368 CYG_TEST_INFO( "Main: calling timer_delete(timer2)");
369 ret = timer_delete( timer2 );
371 CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");
374 CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
376 CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
377 CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );
379 CYG_TEST_PASS_FINISH( "sigsetjmp" );
384 //--------------------------------------------------------------------------
385 // end of sigsetjmp.c