2019-02-10 20:24:11 -05:00
|
|
|
#include "fastlock.h"
|
2019-02-10 22:00:19 -05:00
|
|
|
#include <unistd.h>
|
2019-02-16 14:25:14 -05:00
|
|
|
#include <sys/syscall.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sched.h>
|
2019-02-10 20:24:11 -05:00
|
|
|
|
2019-02-16 14:25:14 -05:00
|
|
|
static_assert(sizeof(pid_t) <= sizeof(fastlock::m_pidOwner), "fastlock::m_pidOwner not large enough");
|
|
|
|
|
|
|
|
static pid_t gettid()
|
|
|
|
{
|
|
|
|
static thread_local int pidCache = -1;
|
|
|
|
if (pidCache == -1)
|
|
|
|
pidCache = syscall(SYS_gettid);
|
|
|
|
return pidCache;
|
|
|
|
}
|
2019-02-15 14:11:05 -05:00
|
|
|
|
2019-02-10 20:24:11 -05:00
|
|
|
extern "C" void fastlock_init(struct fastlock *lock)
|
|
|
|
{
|
2019-02-10 22:00:19 -05:00
|
|
|
lock->m_lock = 0;
|
2019-02-15 14:11:05 -05:00
|
|
|
lock->m_depth = 0;
|
2019-02-10 20:24:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void fastlock_lock(struct fastlock *lock)
|
|
|
|
{
|
2019-02-16 14:25:14 -05:00
|
|
|
if (lock->m_pidOwner == gettid())
|
|
|
|
{
|
|
|
|
++lock->m_depth;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-10 22:00:19 -05:00
|
|
|
while (!__sync_bool_compare_and_swap(&lock->m_lock, 0, 1))
|
|
|
|
{
|
2019-02-16 14:25:14 -05:00
|
|
|
sched_yield();
|
2019-02-10 22:00:19 -05:00
|
|
|
}
|
2019-02-15 14:11:05 -05:00
|
|
|
lock->m_depth = 1;
|
2019-02-16 14:25:14 -05:00
|
|
|
lock->m_pidOwner = gettid();
|
2019-02-10 20:24:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void fastlock_unlock(struct fastlock *lock)
|
|
|
|
{
|
2019-02-15 14:11:05 -05:00
|
|
|
--lock->m_depth;
|
|
|
|
if (lock->m_depth == 0)
|
|
|
|
{
|
|
|
|
lock->m_pidOwner = -1;
|
|
|
|
__sync_bool_compare_and_swap(&lock->m_lock, 1, 0);
|
|
|
|
}
|
2019-02-10 20:24:11 -05:00
|
|
|
}
|
2019-02-10 22:00:19 -05:00
|
|
|
|
2019-02-10 20:24:11 -05:00
|
|
|
extern "C" void fastlock_free(struct fastlock *lock)
|
|
|
|
{
|
|
|
|
// NOP
|
|
|
|
(void)lock;
|
2019-02-15 14:11:05 -05:00
|
|
|
}
|
2019-02-18 22:25:35 -05:00
|
|
|
|
|
|
|
|
|
|
|
bool fastlock::fOwnLock()
|
|
|
|
{
|
|
|
|
return gettid() == m_pidOwner;
|
|
|
|
}
|