161 lines
3.2 KiB
C
161 lines
3.2 KiB
C
/* BeginSourceFile start_stop.c
|
|
|
|
This file creates and deletes threads, so that wdb
|
|
can be tested on thread delete.
|
|
|
|
To compile:
|
|
|
|
cc -Ae +DA1.0 -g -o start_stop -lpthread start_stop.c
|
|
|
|
To run:
|
|
|
|
start_stop --normal run
|
|
start_stop 1 --waits in each thread to keep it alive.
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <pthread.h>
|
|
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define OUTER_LOOP_COUNT 3
|
|
#define N_THREADS 3
|
|
#define MAX_LOCAL_VAL 40
|
|
|
|
/* Uncomment to turn on debugging output */
|
|
/* #define START_DEBUG */
|
|
|
|
/* True if waiting for attach.
|
|
*/
|
|
int wait_here;
|
|
|
|
/* Thing to check for debugging purposes.
|
|
*/
|
|
int a_global = 0;
|
|
|
|
/* Thread-local storage.
|
|
*/
|
|
__thread int a_thread_local;
|
|
|
|
/* Check the results of thread-local storage.
|
|
*/
|
|
int thread_local_val[ N_THREADS ];
|
|
int val_debugger_saw[ N_THREADS ];
|
|
|
|
/* Routine for each thread to run, does nothing.
|
|
*/
|
|
void *spin( vp )
|
|
void * vp;
|
|
{
|
|
int me = (int) vp;
|
|
int i;
|
|
|
|
#ifdef START_DEBUG
|
|
printf( "== In thread %d\n", me );
|
|
#endif
|
|
|
|
a_global++;
|
|
|
|
a_thread_local = 0;
|
|
for( i = 0; i < a_global; i++ ) {
|
|
a_thread_local += i;
|
|
}
|
|
|
|
thread_local_val[ me ] = a_thread_local; /* Line 67 */
|
|
|
|
printf( "== Thread %d, a_thread_local is %d\n",
|
|
(int) vp, a_thread_local );
|
|
|
|
if( wait_here ) {
|
|
/* Extend life of thread to extend life of thread-local var.
|
|
* This makes life easier for human debugging (though you'd
|
|
* probably want to make the delay longer).
|
|
*/
|
|
sleep( 5 );
|
|
}
|
|
}
|
|
|
|
void
|
|
do_pass( pass )
|
|
int pass;
|
|
{
|
|
int i;
|
|
pthread_t t[ N_THREADS ];
|
|
int err;
|
|
|
|
for( i = 0; i < N_THREADS; i++) {
|
|
thread_local_val[i] = 0;
|
|
val_debugger_saw[i] = 0;
|
|
}
|
|
|
|
/* Start N_THREADS threads, then join them so
|
|
* that they are terminated.
|
|
*/
|
|
for( i = 0; i < N_THREADS; i++ ) {
|
|
err = pthread_create( &t[i], NULL, spin, (void *)i );
|
|
if( err != 0 ) {
|
|
printf( "== Start/stop, error in thread %d create\n", i );
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < N_THREADS; i++ ) {
|
|
err = pthread_join(t[i], NULL ); /* Line 105 */
|
|
if( err != 0 ) { /* Line 106 */
|
|
printf( "== Start/stop, error in thread %d join\n", i );
|
|
}
|
|
}
|
|
|
|
i = 10; /* Line 109. Null line for setting bpts on. */
|
|
|
|
/*#ifdef START_DEBUG*/
|
|
for( i = 0; i < N_THREADS; i++) {
|
|
printf( " Local in thread %d was %d, debugger saw %d\n",
|
|
i, thread_local_val[i], val_debugger_saw[i] );
|
|
}
|
|
printf( "== Pass %d done\n", pass );
|
|
/*#endif*/
|
|
|
|
}
|
|
|
|
void
|
|
do_it()
|
|
{
|
|
/* We want to start some threads and then
|
|
* end them, and then do it again and again
|
|
*/
|
|
int i;
|
|
int dummy;
|
|
|
|
for( i = 0; i < OUTER_LOOP_COUNT; i++ ) {
|
|
do_pass( i );
|
|
dummy = i; /* Line 134, null line for setting bps on */
|
|
}
|
|
}
|
|
|
|
main( argc, argv )
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
wait_here = FALSE;
|
|
if((argc > 1) && (0 != argv )) {
|
|
if( 1 == atoi( argv[1] ) )
|
|
wait_here = TRUE;
|
|
}
|
|
|
|
#ifdef START_DEBUG
|
|
printf( "== Test starting\n" );
|
|
#endif
|
|
|
|
do_it();
|
|
|
|
#ifdef START_DEBUG
|
|
printf( "== Test done\n" );
|
|
#endif
|
|
|
|
return(0);
|
|
}
|
|
|
|
/* EndSourceFile */
|