summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.hp/more-steps.c
blob: c5ba1e2686562ff581937245a924c31cb1ccbb13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* BeginSourceFile more_steps.c

  This file creates a lot of threads which then execute
  in parallel, so that wdb can be tested on handling
  simultaneous thread events.

  To compile:

      cc -Ae +DA1.0 -g -o more_steps -lpthread more_steps.c

  To run:
  
     more_threads
*/

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <pthread.h>

#define TRUE 1
#define FALSE 0
#define N_THREADS 3
#define PHASES 3

typedef enum {
  ZERO,
  ONE,
  TWO,
  THREE
} phase_t;

/* Uncomment to turn on debugging output */
/* #define DEBUG  */

/* Locks.
 */
int lock_one; /* Main W, others R */
int lock_two; /* ditto */
int lock_end[ N_THREADS ]; /* Main R, others R[i] */
int phase[ N_THREADS ];

/* Routine for each thread to run.
 */
void *spin( vp )
    void * vp;
{
    int me = (int) vp;
    int i;

    lock_end[ me ] = TRUE;

    phase[ me ] = ONE;

    while( lock_one );

    phase[ me ] = TWO;

    while( lock_two );

    phase[ me ] = THREE;

    lock_end[ me ] = FALSE;
}

void
do_pass()
{
    int i;
    pthread_t t[ N_THREADS ];
    int err;
    int done;

    /* 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 );
        }
    }

    /* Do phase 1.
     */
    lock_one = FALSE;

    /* Do phase 2.
     */
    lock_two = FALSE;
    
    /* Be done.
     */
    done = 0;
    while( !done ) {

       /* Be optimistic.
        */
       done = 1;
       for( i = 0; i < N_THREADS; i++ ) {
           if( lock_end[i] ) {
               /* Thread "i" is not ready yet.
                */
               done = 0;
               break;
           }
       }
    }
    
    /* Finish up
     */
    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. */
}

main( argc, argv )
int    argc;
char **argv;
{
    int i;
    
    /* Init
     */
    lock_one = TRUE;
    lock_two = TRUE;
    for( i = 0; i < N_THREADS; i++ ) {
        lock_end[i] = TRUE;
        phase[i]    = ZERO;
    }
    
    do_pass();
    return(0);
}