-
Notifications
You must be signed in to change notification settings - Fork 63
/
cancel_async.c
130 lines (119 loc) · 3.28 KB
/
cancel_async.c
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
/*
* cancel_async.c
*
* Demonstrate asynchronous cancellation of a compute-bound
* thread.
*
* Special notes: On a Solaris 2.5 uniprocessor, this test will
* hang unless a second LWP is created by calling
* thr_setconcurrency() because threads are not timesliced.
*/
#include <pthread.h>
#include "errors.h"
#define SIZE 10 /* array size */
static int matrixa[SIZE][SIZE];
static int matrixb[SIZE][SIZE];
static int matrixc[SIZE][SIZE];
#ifdef DEBUG
void print_array (int matrix[SIZE][SIZE])
{
int i, j;
int first;
for (i = 0; i < SIZE; i++) {
printf ("[");
first = 1;
for (j = 0; j < SIZE; j++) {
if (!first)
printf (",");
printf ("%x", matrix[i][j]);
first = 0;
}
printf ("]\n");
}
}
#endif
/*
* Loop until cancelled. The thread can be cancelled at any
* point within the inner loop, where asynchronous cancellation
* is enabled. The loop multiplies the two matrices matrixa
* and matrixb.
*/
void *thread_routine (void *arg)
{
int cancel_type, status;
int i, j, k, value = 1;
/*
* Initialize the matrices to something arbitrary.
*/
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++) {
matrixa[i][j] = i;
matrixb[i][j] = j;
}
while (1) {
/*
* Compute the matrix product of matrixa and matrixb.
*/
status = pthread_setcanceltype (
PTHREAD_CANCEL_ASYNCHRONOUS,
&cancel_type);
if (status != 0)
err_abort (status, "Set cancel type");
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++) {
matrixc[i][j] = 0;
for (k = 0; k < SIZE; k++)
matrixc[i][j] += matrixa[i][k] * matrixb[k][j];
}
status = pthread_setcanceltype (
cancel_type,
&cancel_type);
if (status != 0)
err_abort (status, "Set cancel type");
/*
* Copy the result (matrixc) into matrixa to start again
*/
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++)
matrixa[i][j] = matrixc[i][j];
}
}
int main (int argc, char *argv[])
{
pthread_t thread_id;
void *result;
int status;
#ifdef sun
/*
* On Solaris 2.5, threads are not timesliced. To ensure
* that our two threads can run concurrently, we need to
* increase the concurrency level to 2.
*/
DPRINTF (("Setting concurrency level to 2\n"));
thr_setconcurrency (2);
#endif
status = pthread_create (
&thread_id, NULL, thread_routine, NULL);
if (status != 0)
err_abort (status, "Create thread");
sleep (1);
status = pthread_cancel (thread_id);
if (status != 0)
err_abort (status, "Cancel thread");
status = pthread_join (thread_id, &result);
if (status != 0)
err_abort (status, "Join thread");
if (result == PTHREAD_CANCELED)
printf ("Thread cancelled\n");
else
printf ("Thread was not cancelled\n");
#ifdef DEBUG
printf ("Matrix a:\n");
print_array (matrixa);
printf ("\nMatrix b:\n");
print_array (matrixb);
printf ("\nMatrix c:\n");
print_array (matrixc);
#endif
return 0;
}