blob: b6750ab5dd682612d408a2bbf8c6611cce7200fc [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2008 Free Software Foundation, Inc.
3*
Pau Espin Pedrol21d03d32019-07-22 12:05:52 +02004* SPDX-License-Identifier: AGPL-3.0+
dburgess82c46ff2011-10-07 02:40:51 +00005*
6* This software is distributed under the terms of the GNU Affero Public License.
7* See the COPYING file in the main directory for details.
8*
9* This use of this software may be subject to additional restrictions.
10* See the LEGAL file in the main directory for details.
11
12 This program is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Affero General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Affero General Public License for more details.
21
22 You should have received a copy of the GNU Affero General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25*/
26
27
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +020028#include <string.h>
29#include <sys/types.h>
dburgess82c46ff2011-10-07 02:40:51 +000030
31#include "Threads.h"
32#include "Timeval.h"
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +020033#include "Logger.h"
34
Pau Espin Pedrol6c646c32021-03-01 16:35:35 +010035extern "C" {
Pau Espin Pedrol57389402021-02-17 18:25:45 +010036#include <osmocom/core/thread.h>
Pau Espin Pedrol6c646c32021-03-01 16:35:35 +010037}
Pau Espin Pedrol57389402021-02-17 18:25:45 +010038
dburgess82c46ff2011-10-07 02:40:51 +000039using namespace std;
40
Pau Espin Pedrole503c982019-09-13 18:56:08 +020041#ifndef HAVE_ATOMIC_OPS
42 pthread_mutex_t atomic_ops_mutex = PTHREAD_MUTEX_INITIALIZER;
43#endif
dburgess82c46ff2011-10-07 02:40:51 +000044
45
46Mutex gStreamLock; ///< Global lock to control access to cout and cerr.
47
48void lockCout()
49{
50 gStreamLock.lock();
51 Timeval entryTime;
Pau Espin Pedrol17ce7742021-03-01 13:25:28 +010052 cout << entryTime << " " << osmo_gettid() << ": ";
dburgess82c46ff2011-10-07 02:40:51 +000053}
54
55
56void unlockCout()
57{
58 cout << dec << endl << flush;
59 gStreamLock.unlock();
60}
61
62
63void lockCerr()
64{
65 gStreamLock.lock();
66 Timeval entryTime;
Pau Espin Pedrol17ce7742021-03-01 13:25:28 +010067 cerr << entryTime << " " << osmo_gettid() << ": ";
dburgess82c46ff2011-10-07 02:40:51 +000068}
69
70void unlockCerr()
71{
72 cerr << dec << endl << flush;
73 gStreamLock.unlock();
74}
75
76
77
78
79
80
81
82Mutex::Mutex()
83{
84 bool res;
85 res = pthread_mutexattr_init(&mAttribs);
86 assert(!res);
87 res = pthread_mutexattr_settype(&mAttribs,PTHREAD_MUTEX_RECURSIVE);
88 assert(!res);
89 res = pthread_mutex_init(&mMutex,&mAttribs);
90 assert(!res);
91}
92
93
94Mutex::~Mutex()
95{
96 pthread_mutex_destroy(&mMutex);
97 bool res = pthread_mutexattr_destroy(&mAttribs);
98 assert(!res);
99}
100
101
102
103
104/** Block for the signal up to the cancellation timeout. */
105void Signal::wait(Mutex& wMutex, unsigned timeout) const
106{
107 Timeval then(timeout);
108 struct timespec waitTime = then.timespec();
109 pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
110}
111
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +0200112void set_selfthread_name(const char *name)
113{
114 pthread_t selfid = pthread_self();
Pau Espin Pedrol57389402021-02-17 18:25:45 +0100115 pid_t tid = osmo_gettid();
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +0200116 if (pthread_setname_np(selfid, name) == 0) {
117 LOG(INFO) << "Thread "<< selfid << " (task " << tid << ") set name: " << name;
118 } else {
119 char buf[256];
120 int err = errno;
121 char* err_str = strerror_r(err, buf, sizeof(buf));
122 LOG(NOTICE) << "Thread "<< selfid << " (task " << tid << ") set name \"" << name << "\" failed: (" << err << ") " << err_str;
123 }
124}
dburgess82c46ff2011-10-07 02:40:51 +0000125
Pau Espin Pedrol75cb0b92019-04-25 19:33:58 +0200126void thread_enable_cancel(bool cancel)
127{
128 cancel ? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) :
129 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
130}
131
dburgess82c46ff2011-10-07 02:40:51 +0000132void Thread::start(void *(*task)(void*), void *arg)
133{
134 assert(mThread==((pthread_t)0));
135 bool res;
kurtis.heimerl5a872472013-05-31 21:47:25 +0000136 // (pat) Moved initialization to constructor to avoid crash in destructor.
137 //res = pthread_attr_init(&mAttrib);
138 //assert(!res);
Eric Wildac0487e2019-06-17 13:02:44 +0200139 if (mStackSize != 0) {
140 res = pthread_attr_setstacksize(&mAttrib, mStackSize);
141 assert(!res);
142 }
dburgess82c46ff2011-10-07 02:40:51 +0000143 res = pthread_create(&mThread, &mAttrib, task, arg);
144 assert(!res);
145}
146
147
148
149// vim: ts=4 sw=4