GCC Code Coverage Report


Directory: ./
File: pdserv/src/PThread.h
Date: 2024-11-17 04:08:36
Exec Total Coverage
Lines: 35 48 72.9%
Branches: 5 10 50.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright 2017 Richard Hacker (lerichi at gmx dot net)
6 *
7 * This file is part of the pdserv library.
8 *
9 * The pdserv library is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * The pdserv library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *****************************************************************************/
23
24 #ifndef PTHREAD_H
25 #define PTHREAD_H
26
27 #include <pthread.h>
28 #include <stdexcept>
29
30 namespace pthread {
31
32 //////////////////////////////////////////////////////////////////////
33 class RWLock {
34 public:
35 RWLock();
36 ~RWLock();
37
38 70 void writelock() {
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 pthread_rwlock_wrlock(&lock);
40 70 }
41
42 9935 void readlock() {
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9935 times.
9935 pthread_rwlock_rdlock(&lock);
44 9935 }
45
46 10005 void unlock() {
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10005 times.
10005 pthread_rwlock_unlock(&lock);
48 10005 }
49
50 private:
51 pthread_rwlock_t lock;
52 };
53
54 class ReadLock {
55 public:
56 9935 ReadLock(RWLock &l): lock(l) {
57 9935 lock.readlock();
58 9935 }
59
60 19870 ~ReadLock() {
61 9935 lock.unlock();
62 9935 }
63
64 private:
65 RWLock &lock;
66 };
67
68 class WriteLock {
69 public:
70 70 WriteLock(RWLock &l): lock(l) {
71 70 lock.writelock();
72 70 }
73
74 140 ~WriteLock() {
75 70 lock.unlock();
76 70 }
77
78 private:
79 RWLock &lock;
80 };
81
82
83 //////////////////////////////////////////////////////////////////////
84 class Mutex {
85 public:
86 Mutex();
87 ~Mutex();
88
89 10294 void lock() {
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10294 times.
10294 pthread_mutex_lock(&mutex);
91 10294 }
92
93 10294 void unlock() {
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10294 times.
10294 pthread_mutex_unlock(&mutex);
95 10294 }
96
97
98 private:
99 pthread_mutex_t mutex;
100 };
101
102 class MutexLock {
103 public:
104 10294 MutexLock(Mutex &m): mutex(m) {
105 10294 mutex.lock();
106 10294 }
107
108 20588 ~MutexLock() {
109 10294 mutex.unlock();
110 10294 }
111
112 private:
113 Mutex &mutex;
114 };
115
116 //////////////////////////////////////////////////////////////////////
117 template <class T>
118 class AtomicCounter {
119 public:
120 AtomicCounter(const T &initval = T()) {
121 counter = initval;
122 }
123
124 T operator++() {
125 MutexLock l(mutex);
126 return ++counter;
127 }
128
129 T operator--() {
130 MutexLock l(mutex);
131 return --counter;
132 }
133
134 operator T() {
135 MutexLock l(mutex);
136 return counter;
137 }
138
139 private:
140 T counter;
141 Mutex mutex;
142 };
143
144 //////////////////////////////////////////////////////////////////////
145 class Thread {
146 public:
147 // throw this to cancel a Thread from within
148 8 struct CancelThread : std::exception
149 {};
150
151 Thread();
152 virtual ~Thread();
153
154 void set_priority(int);
155 int start();
156 int detach();
157 void terminate() noexcept;
158 void *join() noexcept;
159
160 static void sleep(int msec);
161
162 static constexpr int priority_unset_value = -1;
163
164 protected:
165 295 virtual void initial() {};
166 virtual void run() = 0;
167 virtual void final() {};
168
169 private:
170 static void *start_routine(void *arg);
171
172 pthread_attr_t attr;
173 pthread_t id;
174 int rt_priority = priority_unset_value;
175 bool was_started = false;
176 };
177 }
178
179 #endif // PTHREAD_H
180