threads: add posix/win32 thread wrappers
This commit is contained in:
parent
1a2aa64af6
commit
243716a121
16
Makefile.am
16
Makefile.am
@ -231,6 +231,12 @@ UTIL_FILES = \
|
|||||||
tap.cpp \
|
tap.cpp \
|
||||||
tap.hpp \
|
tap.hpp \
|
||||||
tap.ipp \
|
tap.ipp \
|
||||||
|
threads/barrier.hpp \
|
||||||
|
threads/condition.hpp \
|
||||||
|
threads/mutex.hpp \
|
||||||
|
threads/semaphore.hpp \
|
||||||
|
threads/spinlock.hpp \
|
||||||
|
threads/thread.hpp \
|
||||||
time.cpp \
|
time.cpp \
|
||||||
time.hpp \
|
time.hpp \
|
||||||
tuple.cpp \
|
tuple.cpp \
|
||||||
@ -263,6 +269,12 @@ UTIL_FILES += \
|
|||||||
io_posix.hpp \
|
io_posix.hpp \
|
||||||
posix/dir.hpp \
|
posix/dir.hpp \
|
||||||
posix/dir.cpp \
|
posix/dir.cpp \
|
||||||
|
threads/barrier_posix.cpp \
|
||||||
|
threads/condition_posix.cpp \
|
||||||
|
threads/mutex_posix.cpp \
|
||||||
|
threads/semaphore_posix.cpp \
|
||||||
|
threads/spinlock_posix.cpp \
|
||||||
|
threads/thread_posix.cpp \
|
||||||
time_posix.cpp
|
time_posix.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -270,6 +282,10 @@ if PLATFORM_WIN32
|
|||||||
UTIL_FILES += \
|
UTIL_FILES += \
|
||||||
backtrace_null.cpp \
|
backtrace_null.cpp \
|
||||||
io_win32.cpp \
|
io_win32.cpp \
|
||||||
|
threads/mutex_win32.cpp \
|
||||||
|
threads/mutex_win32.hpp \
|
||||||
|
threads/thread_win32.hpp \
|
||||||
|
threads/thread_win32.cpp \
|
||||||
time_win32.cpp \
|
time_win32.cpp \
|
||||||
win32/registry.hpp \
|
win32/registry.hpp \
|
||||||
win32/registry.cpp
|
win32/registry.cpp
|
||||||
|
35
threads/barrier.hpp
Normal file
35
threads/barrier.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_BARRIER_HPP
|
||||||
|
#define __UTIL_THREADS_BARRIER_HPP
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class barrier {
|
||||||
|
public:
|
||||||
|
barrier (unsigned count);
|
||||||
|
~barrier ();
|
||||||
|
|
||||||
|
void wait (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_barrier_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
44
threads/barrier_posix.cpp
Normal file
44
threads/barrier_posix.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "barrier.hpp"
|
||||||
|
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
using util::threads::barrier;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
barrier::barrier (unsigned count)
|
||||||
|
{
|
||||||
|
pthread_barrier_init (&m_id, nullptr, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
barrier::~barrier ()
|
||||||
|
{
|
||||||
|
pthread_barrier_destroy (&m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
barrier::wait (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_barrier_wait (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
43
threads/condition.hpp
Normal file
43
threads/condition.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_CONDITION_HPP
|
||||||
|
#define __UTIL_THREADS_CONDITION_HPP
|
||||||
|
|
||||||
|
#include "mutex.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class condition {
|
||||||
|
public:
|
||||||
|
condition ();
|
||||||
|
~condition ();
|
||||||
|
|
||||||
|
void wait (mutex&);
|
||||||
|
void wait (mutex&, std::chrono::nanoseconds);
|
||||||
|
|
||||||
|
void signal (void);
|
||||||
|
void broadcast (void);
|
||||||
|
|
||||||
|
pthread_cond_t native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_cond_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
81
threads/condition_posix.cpp
Normal file
81
threads/condition_posix.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "condition.hpp"
|
||||||
|
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
using util::threads::condition;
|
||||||
|
using util::threads::mutex;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
condition::condition ()
|
||||||
|
{
|
||||||
|
auto err = pthread_cond_init (&m_id, nullptr);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
condition::~condition ()
|
||||||
|
{
|
||||||
|
auto err = pthread_cond_destroy (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
condition::signal (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_cond_signal (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
condition::broadcast (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_cond_broadcast (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
condition::wait (mutex &m)
|
||||||
|
{
|
||||||
|
auto mutid = m.native ();
|
||||||
|
auto err = pthread_cond_wait (&m_id, &mutid);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
condition::wait (mutex &m, std::chrono::nanoseconds t)
|
||||||
|
{
|
||||||
|
struct timespec abstime;
|
||||||
|
abstime.tv_sec = std::chrono::duration_cast<std::chrono::seconds> (t).count ();
|
||||||
|
abstime.tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds> (t).count ();
|
||||||
|
|
||||||
|
auto mutid = m.native ();
|
||||||
|
|
||||||
|
auto err = pthread_cond_timedwait (&m_id, &mutid, &abstime);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
39
threads/mutex.hpp
Normal file
39
threads/mutex.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_MUTEX_HPP
|
||||||
|
#define __UTIL_THREADS_MUTEX_HPP
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class mutex {
|
||||||
|
public:
|
||||||
|
mutex ();
|
||||||
|
~mutex ();
|
||||||
|
|
||||||
|
void lock (void);
|
||||||
|
bool try_lock (void);
|
||||||
|
void unlock (void);
|
||||||
|
|
||||||
|
pthread_mutex_t native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
63
threads/mutex_posix.cpp
Normal file
63
threads/mutex_posix.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mutex.hpp"
|
||||||
|
|
||||||
|
#include "../except.hpp"
|
||||||
|
#include "../debug.hpp"
|
||||||
|
|
||||||
|
using util::threads::mutex;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
mutex::mutex ()
|
||||||
|
{
|
||||||
|
auto err = pthread_mutex_init (&m_id, nullptr);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
mutex::~mutex ()
|
||||||
|
{
|
||||||
|
auto err = pthread_mutex_destroy (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
mutex::lock (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_mutex_lock (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
mutex::try_lock (void)
|
||||||
|
{
|
||||||
|
switch (auto err = pthread_mutex_trylock (&m_id)) {
|
||||||
|
case 0: return true;
|
||||||
|
case EBUSY: return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errno_error::throw_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable ();
|
||||||
|
}
|
71
threads/mutex_win32.cpp
Normal file
71
threads/mutex_win32.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mutex_win32.hpp"
|
||||||
|
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
using util::threads::win32::mutex;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
mutex::mutex ():
|
||||||
|
m_id (CreateMutex (nullptr, false, nullptr))
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool
|
||||||
|
mutex::lock (void)
|
||||||
|
{
|
||||||
|
switch (WaitForSingleObject (m_id, INFINITE)) {
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case WAIT_FAILED:
|
||||||
|
win32_error::throw_code ();
|
||||||
|
default:
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
mutex::lock (std::chrono::nanoseconds ns)
|
||||||
|
{
|
||||||
|
auto ms = std::chrono::duration_cast<std::chrono::milliseconds> (ns).count ();
|
||||||
|
switch (WaitForSingleObject (m_id, ms)) {
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return true;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case WAIT_FAILED:
|
||||||
|
win32_error::throw_code ();
|
||||||
|
default:
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
mutex::unlock (void)
|
||||||
|
{
|
||||||
|
if (ReleaseMutex (m_id))
|
||||||
|
win32_error::throw_code ();
|
||||||
|
}
|
41
threads/mutex_win32.hpp
Normal file
41
threads/mutex_win32.hpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_MUTEX_WIN32_HPP
|
||||||
|
#define __UTIL_THREADS_MUTEX_WIN32_HPP
|
||||||
|
|
||||||
|
#include "io.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace util { namespace threads { namespace win32 {
|
||||||
|
class mutex {
|
||||||
|
public:
|
||||||
|
mutex ();
|
||||||
|
|
||||||
|
bool lock (void);
|
||||||
|
bool lock (std::chrono::nanoseconds);
|
||||||
|
void unlock (void);
|
||||||
|
|
||||||
|
handle& native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
handle m_id;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
40
threads/semaphore.hpp
Normal file
40
threads/semaphore.hpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_SEMAPHORE_HPP
|
||||||
|
#define __UTIL_THREADS_SEMAPHORE_HPP
|
||||||
|
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class semaphore {
|
||||||
|
public:
|
||||||
|
semaphore (unsigned value = 0);
|
||||||
|
~semaphore ();
|
||||||
|
|
||||||
|
void wait (void);
|
||||||
|
bool try_wait (void);
|
||||||
|
void post (void);
|
||||||
|
|
||||||
|
sem_t native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
sem_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
72
threads/semaphore_posix.cpp
Normal file
72
threads/semaphore_posix.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "semaphore.hpp"
|
||||||
|
|
||||||
|
#include "debug.hpp"
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
using util::threads::semaphore;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
semaphore::semaphore (unsigned value)
|
||||||
|
{
|
||||||
|
auto err = sem_init (&m_id, false, value);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
semaphore::~semaphore ()
|
||||||
|
{
|
||||||
|
auto err = sem_destroy (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
semaphore::wait (void)
|
||||||
|
{
|
||||||
|
auto err = sem_wait (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
semaphore::try_wait (void)
|
||||||
|
{
|
||||||
|
switch (auto err = sem_wait (&m_id)) {
|
||||||
|
case 0: return true;
|
||||||
|
case EAGAIN: return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errno_error::throw_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
semaphore::post (void)
|
||||||
|
{
|
||||||
|
auto err = sem_post (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
1
threads/spinlock.cpp
Normal file
1
threads/spinlock.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "spinlock.hpp"
|
38
threads/spinlock.hpp
Normal file
38
threads/spinlock.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_SPINLOCK_HPP
|
||||||
|
#define __UTIL_THREADS_SPINLOCK_HPP
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class spinlock {
|
||||||
|
public:
|
||||||
|
spinlock ();
|
||||||
|
~spinlock ();
|
||||||
|
|
||||||
|
void lock (void);
|
||||||
|
void unlock (void);
|
||||||
|
|
||||||
|
pthread_spinlock_t native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_spinlock_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
55
threads/spinlock_posix.cpp
Normal file
55
threads/spinlock_posix.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spinlock.hpp"
|
||||||
|
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
using util::threads::spinlock;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
spinlock::spinlock ()
|
||||||
|
{
|
||||||
|
auto err = pthread_spin_init (&m_id, PTHREAD_PROCESS_PRIVATE);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
spinlock::~spinlock ()
|
||||||
|
{
|
||||||
|
auto err = pthread_spin_destroy (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
spinlock::lock (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_spin_lock (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
spinlock::unlock (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_spin_unlock (&m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
30
threads/thread.hpp
Normal file
30
threads/thread.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_THREAD_HPP
|
||||||
|
#define __UTIL_THREADS_THREAD_HPP
|
||||||
|
|
||||||
|
#include "platform.hpp"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_LINUX)
|
||||||
|
#include "thread_posix.hpp"
|
||||||
|
#elif defined(PLATFORM_WIN32)
|
||||||
|
#include "thread_win32.hpp"
|
||||||
|
#else
|
||||||
|
#error "Unhandled platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
74
threads/thread_posix.cpp
Normal file
74
threads/thread_posix.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "thread.hpp"
|
||||||
|
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
using util::threads::thread;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
thread::join (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_join (m_id, nullptr);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
thread::kill (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_cancel (m_id);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
thread::yield (void)
|
||||||
|
{
|
||||||
|
auto err = pthread_yield ();
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
unsigned
|
||||||
|
thread::concurrency (void)
|
||||||
|
{
|
||||||
|
auto val = sysconf (_SC_NPROCESSORS_ONLN);
|
||||||
|
if (val < 0)
|
||||||
|
errno_error::throw_code ();
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// pthread entry point
|
||||||
|
void*
|
||||||
|
thread::dispatch (void *func)
|
||||||
|
{
|
||||||
|
typedef decltype(thread::m_func) func_t;
|
||||||
|
(*reinterpret_cast<func_t*> (func)) ();
|
||||||
|
return nullptr;
|
||||||
|
}
|
54
threads/thread_posix.hpp
Normal file
54
threads/thread_posix.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_THREAD_POSIX_HPP
|
||||||
|
#define __UTIL_THREADS_THREAD_POSIX_HPP
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace util { namespace threads {
|
||||||
|
class thread {
|
||||||
|
public:
|
||||||
|
template <typename Func, typename ...Args>
|
||||||
|
thread (Func &&_func, Args &&..._args);
|
||||||
|
thread (thread&&);
|
||||||
|
~thread ();
|
||||||
|
|
||||||
|
thread (const thread&) = delete;
|
||||||
|
thread& operator= (const thread&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
void join (void);
|
||||||
|
void kill (void);
|
||||||
|
|
||||||
|
static void yield (void);
|
||||||
|
static unsigned concurrency (void);
|
||||||
|
|
||||||
|
pthread_t native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void* dispatch (void*);
|
||||||
|
|
||||||
|
std::function<void(void)> m_func;
|
||||||
|
pthread_t m_id;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
#include "thread_posix.ipp"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
38
threads/thread_posix.ipp
Normal file
38
threads/thread_posix.ipp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __UTIL_THREAD_IPP
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
#define __UTIL_THREAD_IPP
|
||||||
|
|
||||||
|
#include "tuple.hpp"
|
||||||
|
#include "except.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Func, typename ...Args>
|
||||||
|
util::threads::thread::thread (Func &&_func, Args&&..._args):
|
||||||
|
m_func ([
|
||||||
|
func = std::forward<Func> (_func),
|
||||||
|
args = std::make_tuple (std::forward<Args> (_args)...)
|
||||||
|
] (void) {
|
||||||
|
return tuple::call (func, args);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
auto err = pthread_create (&m_id, nullptr, dispatch, &m_func);
|
||||||
|
errno_error::try_code (err);
|
||||||
|
}
|
31
threads/thread_win32.cpp
Normal file
31
threads/thread_win32.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "thread_win32.hpp"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
using util::threads::win32::thread;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
unsigned
|
||||||
|
thread::concurrency (void)
|
||||||
|
{
|
||||||
|
SYSTEM_INFO info;
|
||||||
|
GetSystemInfo (&info);
|
||||||
|
return info.dwNumberOfProcessors;
|
||||||
|
}
|
51
threads/thread_win32.hpp
Normal file
51
threads/thread_win32.hpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_THREADS_THREAD_WIN32_HPP
|
||||||
|
#define __UTIL_THREADS_THREAD_WIN32_HPP
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "io.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace threads { inline namespace win32 {
|
||||||
|
class thread {
|
||||||
|
public:
|
||||||
|
template <typename Func, typename ...Args>
|
||||||
|
thread (Func &&_func, Args &&..._args) { }
|
||||||
|
|
||||||
|
thread (thread&&);
|
||||||
|
~thread ();
|
||||||
|
|
||||||
|
thread (const thread&) = delete;
|
||||||
|
thread& operator= (const thread&) = delete;
|
||||||
|
|
||||||
|
void join (void);
|
||||||
|
void kill (void);
|
||||||
|
|
||||||
|
static void yield (void);
|
||||||
|
static unsigned concurrency (void);
|
||||||
|
|
||||||
|
handle native (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(void)> m_func;
|
||||||
|
handle m_id;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user