Squashed 'third_party/apriltag/' content from commit 3e8e974d0
git-subtree-dir: third_party/apriltag
git-subtree-split: 3e8e974d0d8d6ab318abf56d87506d15d7f2cc35
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Change-Id: I04ba3cb2106b6813a1013d57aa8074c26f856598
diff --git a/common/pthreads_cross.cpp b/common/pthreads_cross.cpp
new file mode 100644
index 0000000..f772191
--- /dev/null
+++ b/common/pthreads_cross.cpp
@@ -0,0 +1,259 @@
+/**
+Copyright John Schember <john@nachtimwald.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+
+#include "common/pthreads_cross.h"
+#include <time.h>
+
+#ifdef _WIN32
+
+typedef struct {
+ SRWLOCK lock;
+ bool exclusive;
+} pthread_rwlock_t;
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
+
+int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
+{
+ (void) attr;
+
+ if (thread == NULL || start_routine == NULL)
+ return 1;
+
+ *thread = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
+ if (*thread == NULL)
+ return 1;
+ return 0;
+}
+
+int pthread_join(pthread_t thread, void **value_ptr)
+{
+ (void)value_ptr;
+ WaitForSingleObject(thread, INFINITE);
+ CloseHandle(thread);
+ return 0;
+}
+
+int pthread_detach(pthread_t thread)
+{
+ CloseHandle(thread);
+ return 0;
+}
+
+int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
+{
+ (void)attr;
+
+ if (mutex == NULL)
+ return 1;
+
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return 1;
+ DeleteCriticalSection(mutex);
+ return 0;
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return 1;
+ EnterCriticalSection(mutex);
+ return 0;
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ if (mutex == NULL)
+ return 1;
+ LeaveCriticalSection(mutex);
+ return 0;
+}
+
+int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr)
+{
+ (void)attr;
+ if (cond == NULL)
+ return 1;
+ InitializeConditionVariable(cond);
+ return 0;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ /* Windows does not have a destroy for conditionals */
+ (void)cond;
+ return 0;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ if (cond == NULL || mutex == NULL)
+ return 1;
+ return pthread_cond_timedwait(cond, mutex, NULL);
+}
+
+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ if (cond == NULL || mutex == NULL)
+ return 1;
+ if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime)))
+ return 1;
+ return 0;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ if (cond == NULL)
+ return 1;
+ WakeConditionVariable(cond);
+ return 0;
+}
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ if (cond == NULL)
+ return 1;
+ WakeAllConditionVariable(cond);
+ return 0;
+}
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+ (void)attr;
+ if (rwlock == NULL)
+ return 1;
+ InitializeSRWLock(&(rwlock->lock));
+ rwlock->exclusive = false;
+ return 0;
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+{
+ (void)rwlock;
+ return 0;
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+ if (rwlock == NULL)
+ return 1;
+ AcquireSRWLockShared(&(rwlock->lock));
+ return 0;
+}
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+ if (rwlock == NULL)
+ return 1;
+ return !TryAcquireSRWLockShared(&(rwlock->lock));
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+ if (rwlock == NULL)
+ return 1;
+ AcquireSRWLockExclusive(&(rwlock->lock));
+ rwlock->exclusive = true;
+ return 0;
+}
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+{
+ BOOLEAN ret;
+
+ if (rwlock == NULL)
+ return 1;
+
+ ret = TryAcquireSRWLockExclusive(&(rwlock->lock));
+ if (ret)
+ rwlock->exclusive = true;
+ return ret;
+}
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+ if (rwlock == NULL)
+ return 1;
+
+ if (rwlock->exclusive) {
+ rwlock->exclusive = false;
+ ReleaseSRWLockExclusive(&(rwlock->lock));
+ } else {
+ ReleaseSRWLockShared(&(rwlock->lock));
+ }
+ return 0;
+}
+
+int sched_yield() {
+ return (int)SwitchToThread();
+}
+
+void ms_to_timespec(struct timespec *ts, unsigned int ms)
+{
+ if (ts == NULL)
+ return;
+ ts->tv_sec = (ms / 1000) + time(NULL);
+ ts->tv_nsec = (ms % 1000) * 1000000;
+}
+
+unsigned int timespec_to_ms(const struct timespec *abstime)
+{
+ DWORD t;
+
+ if (abstime == NULL)
+ return INFINITE;
+
+ t = ((abstime->tv_sec - time(NULL)) * 1000) + (abstime->tv_nsec / 1000000);
+ if (t < 0)
+ t = 1;
+ return t;
+}
+
+unsigned int pcthread_get_num_procs()
+{
+ SYSTEM_INFO sysinfo;
+
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+}
+
+#else
+
+#include <unistd.h>
+unsigned int pcthread_get_num_procs()
+{
+ return (unsigned int)sysconf(_SC_NPROCESSORS_ONLN);
+}
+#endif