summaryrefslogtreecommitdiff
path: root/tests/test02.c
blob: 1cd0c1abfe897468aa70e25ba19a359bd81bf1d9 (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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include "linen.h"


#define NUM_THREADS 10


/* Argument for thread function */
typedef struct {
	useconds_t delay;
	int id;
} f_arg_t;


/* Function for threads to run */
void* f(void* arg) {
	f_arg_t* a = (f_arg_t*)arg;
	usleep(a->delay);
	printf("    Hello from thread #%d!\n", a->id);
	return (void*)&(a->delay);
}


void main() {
	printf("\x1B[1mTEST 02: threads print after random delay "
	       "while getting joined consecutively:\x1B[0m\n");

	/* Thread handles and arguments */
	linen_thread_t ts[NUM_THREADS];
	f_arg_t args[NUM_THREADS];

	/* Set arguments */
	srand(time(NULL));
	for (int i = 0; i < NUM_THREADS; i++) {
		args[i].delay = (useconds_t)rand() % 1000000;
		args[i].id = i;
	}

	/* Spawn threads */
	for (int i = 0; i < NUM_THREADS; i++) {
		int r = linen_thread_create(&ts[i], f, (void*)&args[i]);
		if (r) {
			printf("    Failed to spawn thread #%d with error %d\n", i, r);
		}
	}

	/* Wait for each thread to finish in order, and print its argument.
	 * The first message only prints once thread #0 is done, and so on. */
	for (int i = 0; i < NUM_THREADS; i++) {
		useconds_t* pd;
		int r = linen_thread_finish(ts[i], (void**)&pd);
		if (r) {
			printf("    Failed to join thread #%d with error %d\n", i, r);
		} else {
			printf("    Thread #%d slept for %dms\n", i, *pd / 1000);
		}
	}
}