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