Implement try_lock
This commit is contained in:
parent
ebf0ae3e97
commit
d016b967c5
@ -774,6 +774,11 @@ void aeAcquireLock()
|
|||||||
g_lock.lock();
|
g_lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int aeTryAcquireLock()
|
||||||
|
{
|
||||||
|
return g_lock.try_lock();
|
||||||
|
}
|
||||||
|
|
||||||
void aeReleaseLock()
|
void aeReleaseLock()
|
||||||
{
|
{
|
||||||
g_lock.unlock();
|
g_lock.unlock();
|
||||||
|
1
src/ae.h
1
src/ae.h
@ -159,6 +159,7 @@ int aeGetSetSize(aeEventLoop *eventLoop);
|
|||||||
int aeResizeSetSize(aeEventLoop *eventLoop, int setsize);
|
int aeResizeSetSize(aeEventLoop *eventLoop, int setsize);
|
||||||
|
|
||||||
void aeAcquireLock();
|
void aeAcquireLock();
|
||||||
|
int aeTryAcquireLock();
|
||||||
void aeReleaseLock();
|
void aeReleaseLock();
|
||||||
int aeThreadOwnsLock();
|
int aeThreadOwnsLock();
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ static pid_t gettid()
|
|||||||
|
|
||||||
extern "C" void fastlock_init(struct fastlock *lock)
|
extern "C" void fastlock_init(struct fastlock *lock)
|
||||||
{
|
{
|
||||||
lock->m_active = 0;
|
lock->m_ticket.m_active = 0;
|
||||||
lock->m_avail = 0;
|
lock->m_ticket.m_avail = 0;
|
||||||
lock->m_depth = 0;
|
lock->m_depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,12 +66,12 @@ extern "C" void fastlock_lock(struct fastlock *lock)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned myticket = __atomic_fetch_add(&lock->m_avail, 1, __ATOMIC_ACQ_REL);
|
unsigned myticket = __atomic_fetch_add(&lock->m_ticket.m_avail, 1, __ATOMIC_ACQ_REL);
|
||||||
|
|
||||||
if (__atomic_load_4(&lock->m_active, __ATOMIC_ACQUIRE) != myticket)
|
if (__atomic_load_2(&lock->m_ticket.m_active, __ATOMIC_ACQUIRE) != myticket)
|
||||||
{
|
{
|
||||||
int cloops = 1;
|
int cloops = 1;
|
||||||
while (__atomic_load_4(&lock->m_active, __ATOMIC_ACQUIRE) != myticket)
|
while (__atomic_load_2(&lock->m_ticket.m_active, __ATOMIC_ACQUIRE) != myticket)
|
||||||
{
|
{
|
||||||
if ((++cloops % 1024*1024) == 0)
|
if ((++cloops % 1024*1024) == 0)
|
||||||
sched_yield();
|
sched_yield();
|
||||||
@ -83,6 +83,33 @@ extern "C" void fastlock_lock(struct fastlock *lock)
|
|||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int fastlock_trylock(struct fastlock *lock)
|
||||||
|
{
|
||||||
|
if ((int)__atomic_load_4(&lock->m_pidOwner, __ATOMIC_ACQUIRE) == gettid())
|
||||||
|
{
|
||||||
|
++lock->m_depth;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cheap test
|
||||||
|
if (lock->m_ticket.m_active != lock->m_ticket.m_avail)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint16_t active = __atomic_load_2(&lock->m_ticket.m_active, __ATOMIC_ACQUIRE);
|
||||||
|
uint16_t next = active + 1;
|
||||||
|
|
||||||
|
struct ticket ticket_expect { active, active };
|
||||||
|
struct ticket ticket_setiflocked { active, next };
|
||||||
|
if (__atomic_compare_exchange(&lock->m_ticket, &ticket_expect, &ticket_setiflocked, true /*strong*/, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE))
|
||||||
|
{
|
||||||
|
lock->m_depth = 1;
|
||||||
|
__atomic_store_4(&lock->m_pidOwner, gettid(), __ATOMIC_RELEASE);
|
||||||
|
__sync_synchronize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void fastlock_unlock(struct fastlock *lock)
|
extern "C" void fastlock_unlock(struct fastlock *lock)
|
||||||
{
|
{
|
||||||
--lock->m_depth;
|
--lock->m_depth;
|
||||||
@ -90,7 +117,7 @@ extern "C" void fastlock_unlock(struct fastlock *lock)
|
|||||||
{
|
{
|
||||||
lock->m_pidOwner = -1;
|
lock->m_pidOwner = -1;
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
__atomic_fetch_add(&lock->m_active, 1, __ATOMIC_ACQ_REL);
|
__atomic_fetch_add(&lock->m_ticket.m_active, 1, __ATOMIC_ACQ_REL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -8,6 +9,7 @@ extern "C" {
|
|||||||
struct fastlock;
|
struct fastlock;
|
||||||
void fastlock_init(struct fastlock *lock);
|
void fastlock_init(struct fastlock *lock);
|
||||||
void fastlock_lock(struct fastlock *lock);
|
void fastlock_lock(struct fastlock *lock);
|
||||||
|
int fastlock_trylock(struct fastlock *lock);
|
||||||
void fastlock_unlock(struct fastlock *lock);
|
void fastlock_unlock(struct fastlock *lock);
|
||||||
void fastlock_free(struct fastlock *lock);
|
void fastlock_free(struct fastlock *lock);
|
||||||
|
|
||||||
@ -16,10 +18,14 @@ void fastlock_free(struct fastlock *lock);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ticket
|
||||||
|
{
|
||||||
|
uint16_t m_active;
|
||||||
|
uint16_t m_avail;
|
||||||
|
};
|
||||||
struct fastlock
|
struct fastlock
|
||||||
{
|
{
|
||||||
volatile unsigned m_active;
|
volatile struct ticket m_ticket;
|
||||||
volatile unsigned m_avail;
|
|
||||||
|
|
||||||
volatile int m_pidOwner;
|
volatile int m_pidOwner;
|
||||||
volatile int m_depth;
|
volatile int m_depth;
|
||||||
@ -35,6 +41,11 @@ struct fastlock
|
|||||||
fastlock_lock(this);
|
fastlock_lock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
return !!fastlock_trylock(this);
|
||||||
|
}
|
||||||
|
|
||||||
void unlock()
|
void unlock()
|
||||||
{
|
{
|
||||||
fastlock_unlock(this);
|
fastlock_unlock(this);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user