1//------------------------------------------------------------------------------
2// Copyright (c) 2016 by Lukasz Janyst <lukasz@jany.st>
3//------------------------------------------------------------------------------
4// This file is part of thread-bites.
5//
6// thread-bites is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// thread-bites is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with thread-bites. If not, see <http://www.gnu.org/licenses/>.
18//------------------------------------------------------------------------------
19
20#include <tb.h>
21#include <string.h>
22
23tbthread_rwlock_t lock = TBTHREAD_RWLOCK_INIT;
24int a = 0;
25int b = 0;
26
27//------------------------------------------------------------------------------
28// Thread function
29//------------------------------------------------------------------------------
30void *reader_func(void *arg)
31{
32 tbthread_t self = tbthread_self();
33 tbprint("[thread 0x%llx] Starting a reader\n", self);
34 while(1) {
35 tbthread_rwlock_rdlock(&lock);
36 int br = (b == 30);
37 if(a != b) tbprint("[thread 0x%llx] a != b\n", self);
38 tbthread_rwlock_unlock(&lock);
39 if(br)
40 break;
41 }
42 tbprint("[thread 0x%llx] Finishing a reader\n", self);
43 return 0;
44}
45
46//------------------------------------------------------------------------------
47// Thread function
48//------------------------------------------------------------------------------
49void *writer_func(void *arg)
50{
51 tbthread_t self = tbthread_self();
52 tbprint("[thread 0x%llx] Starting a writer\n", self);
53 for(int i = 0; i < 10; ++i) {
54 tbthread_rwlock_wrlock(&lock);
55 a = b+1;
56 tbprint("[thread 0x%llx] Bumped a to %d\n", self, a);
57 for(uint64_t z = 0; z < 200000000ULL; ++z);
58 b = a;
59 tbprint("[thread 0x%llx] Bumped b to %d\n", self, b);
60 tbthread_rwlock_unlock(&lock);
61 tbsleep(4);
62 }
63 tbprint("[thread 0x%llx] Finishing a writer\n", self);
64 return 0;
65}
66
67//------------------------------------------------------------------------------
68// Start the show
69//------------------------------------------------------------------------------
70int main(int argc, char **argv)
71{
72 tbthread_init();
73
74 tbthread_t thread[10];
75 void *(*thfunc[10])(void *);
76 tbthread_attr_t attr;
77 int st = 0;
78
79 for(int i = 0; i < 7; ++i)
80 thfunc[i] = reader_func;
81 for(int i = 7; i < 10; ++i)
82 thfunc[i] = writer_func;
83
84 //----------------------------------------------------------------------------
85 // Spawn the threads
86 //----------------------------------------------------------------------------
87 tbthread_attr_init(&attr);
88 for(int i = 0; i < 10; ++i) {
89 st = tbthread_create(&thread[i], &attr, thfunc[i], 0);
90 if(st != 0) {
91 tbprint("Failed to spawn thread %d: %s\n", i, tbstrerror(-st));
92 goto exit;
93 }
94 }
95
96 tbprint("[thread main] Threads spawned successfully\n");
97
98 for(int i = 0; i < 10; ++i) {
99 st = tbthread_join(thread[i], 0);
100 if(st != 0) {
101 tbprint("Failed to join thread %d: %s\n", i, tbstrerror(-st));
102 goto exit;
103 }
104 }
105
106 tbprint("[thread main] Threads joined\n");
107
108exit:
109 tbthread_finit();
110 return st;
111};
112