2023-08-15 08:54:02 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <threads.h>
|
2023-08-26 11:35:18 +00:00
|
|
|
#include <stdatomic.h>
|
2023-08-27 02:51:35 +00:00
|
|
|
#include <cia/sync.h>
|
2023-08-15 08:54:02 +00:00
|
|
|
|
2023-08-26 07:28:59 +00:00
|
|
|
static void print_string_n(char *str, u64 len) {
|
|
|
|
fwrite(str, 1, len, stdout);
|
|
|
|
}
|
|
|
|
static void print_char(char c) {
|
|
|
|
print_string_n(&c, 1);
|
|
|
|
}
|
|
|
|
static void print_string(char *str) {
|
2023-08-26 02:53:58 +00:00
|
|
|
int str_len = 0;
|
|
|
|
while(str[str_len] != 0) {
|
2023-08-26 07:28:59 +00:00
|
|
|
str_len += 1;
|
|
|
|
}
|
|
|
|
print_string_n(str, str_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void print_int(i64 number) {
|
|
|
|
if(number < 0) {
|
|
|
|
print_char('-');
|
|
|
|
number = -number;
|
2023-08-26 02:53:58 +00:00
|
|
|
}
|
2023-08-26 07:28:59 +00:00
|
|
|
char buf[20];
|
|
|
|
buf[19] = 0;
|
|
|
|
char *p = buf + sizeof buf - 1;
|
|
|
|
do {
|
|
|
|
*--p = (number%10) + '0';
|
|
|
|
number /= 10;
|
|
|
|
} while(number > 0);
|
|
|
|
print_string(p);
|
2023-08-26 02:53:58 +00:00
|
|
|
}
|
|
|
|
|
2023-08-27 02:51:35 +00:00
|
|
|
static Cia_Mutex g_print_mutex;
|
|
|
|
static Cia_Mutex g_mutex;
|
|
|
|
static volatile _Atomic i64 n_completed = 0;
|
|
|
|
static volatile i64 counter = 0;
|
2023-08-26 07:28:59 +00:00
|
|
|
|
2023-08-15 08:54:02 +00:00
|
|
|
int thrd_func(void *arg) {
|
2023-08-26 07:28:59 +00:00
|
|
|
print_string("child thread: ok!\n");
|
|
|
|
for(int i = 0; i < 100000; ++i) {
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_lock(&g_mutex);
|
2023-08-26 07:28:59 +00:00
|
|
|
counter += 1;
|
2023-08-27 02:51:35 +00:00
|
|
|
print_int(counter);
|
|
|
|
print_char('\n');
|
|
|
|
cia_mutex_unlock(&g_mutex);
|
2023-08-26 07:28:59 +00:00
|
|
|
}
|
2023-08-27 02:51:35 +00:00
|
|
|
atomic_fetch_add(&n_completed, 1);
|
|
|
|
for(;;) {
|
|
|
|
if(n_completed == 2) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cia_mutex_lock(&g_print_mutex);
|
2023-08-26 07:28:59 +00:00
|
|
|
print_string("child thread: counter = ");
|
|
|
|
print_int(counter);
|
|
|
|
print_char('\n');
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_unlock(&g_print_mutex);
|
|
|
|
exit(1);
|
2023-08-15 08:54:02 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
2023-08-26 07:28:59 +00:00
|
|
|
print_string("main thread: before\n");
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_init(&g_mutex);
|
|
|
|
cia_mutex_init(&g_print_mutex);
|
2023-08-15 08:54:02 +00:00
|
|
|
thrd_t thrd;
|
2023-08-26 07:28:59 +00:00
|
|
|
int status = thrd_create(&thrd, thrd_func, NULL);
|
|
|
|
if(status == thrd_error) {
|
|
|
|
print_string("main thread: error creating child thread\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
print_string("main thread: after!\n");
|
|
|
|
for(int i = 0; i < 100000; ++i) {
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_lock(&g_mutex);
|
2023-08-26 07:28:59 +00:00
|
|
|
counter += 1;
|
2023-08-27 02:51:35 +00:00
|
|
|
print_int(counter);
|
|
|
|
print_char('\n');
|
|
|
|
cia_mutex_unlock(&g_mutex);
|
|
|
|
}
|
|
|
|
atomic_fetch_add(&n_completed, 1);
|
|
|
|
for(;;) {
|
|
|
|
if(n_completed == 2) {
|
|
|
|
break;
|
|
|
|
}
|
2023-08-26 07:28:59 +00:00
|
|
|
}
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_lock(&g_print_mutex);
|
2023-08-26 07:28:59 +00:00
|
|
|
print_string("main thread: counter = ");
|
|
|
|
print_int(counter);
|
|
|
|
print_char('\n');
|
2023-08-27 02:51:35 +00:00
|
|
|
cia_mutex_unlock(&g_print_mutex);
|
2023-08-15 08:54:02 +00:00
|
|
|
return 0;
|
|
|
|
}
|