linux 用户态锁实现,Linux下用户态自旋锁的实现

#include

#include

#include

#include

#include

#define SPIN_LOCK 1

static uint32_t atomic_cmp_set(uint32_t *lock, uint32_t old, uint32_t set)

{

uint8_t rslt = 0;

asm volatile ("lock;" // lock if SMP

"cmpxchgl %3, %1;"

"sete %0;"

: "=a" (rslt)

: "m" (*lock), "a" (old), "r" (set)

: "cc", "memory");

return rslt;

}

static uint32_t g_continue = 1;

static volatile uint32_t g_count1 = 0;

static volatile uint32_t g_count2 = 0;

static uint32_t g_lock = 0;

static void *thread_func(void *p_param)

{

while (g_continue) {

#if SPIN_LOCK

while (!atomic_cmp_set(&g_lock, 0, 1)) {

sched_yield();

}

#endif

++g_count1;

++g_count2;

#if SPIN_LOCK

g_lock = 0;

#endif

}

return NULL;

}

int main(int argc, char *argv[])

{

pthread_t t1 = 0, t2 = 0;

pthread_create(&t1, NULL, &thread_func, NULL);

pthread_create(&t2, NULL, &thread_func, NULL);

sleep(1);

g_continue = 0;

pthread_join(t1, NULL);

pthread_join(t2, NULL);

fprintf(stderr,

"%u, %u\n",

g_count1,

g_count2);

return 0;

}

##########################################################################################

##########################################################################################

增加进程同步

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define THREAD          0

#define SPIN_LOCK       1

#if SPIN_LOCK

static uint32_t atomic_cmp_set(uint32_t *lock, uint32_t old, uint32_t set)

{

uint8_t rslt = 0;

assert(NULL != lock);

asm volatile ("lock;" // lock if SMP

"cmpxchgl %3, %1;"

"sete %0;"

: "=a" (rslt)

: "m" (*lock), "a" (old), "r" (set)

: "cc", "memory");

return rslt;

}

#endif

#if THREAD

static uint32_t g_continue = 1;

#else

static void *gp_continue = NULL;

#endif

#if THREAD

static volatile uint32_t g_count1 = 0;

static volatile uint32_t g_count2 = 0;

#else

static volatile void *gp_count1 = 0;

static volatile void *gp_count2 = 0;

#endif

static int shmid = 0;

#if SPIN_LOCK

#if THREAD

static uint32_t g_lock = 0;

#else

static void *gp_lock = NULL;

#endif

#endif

static void *thread_func(void *p_param)

{

#if THREAD

while (g_continue) {

#else

while (*(uint32_t *)gp_continue) {

#endif

#if SPIN_LOCK

#if THREAD

while (!atomic_cmp_set(&g_lock, 0, 1)) {

#else

while (!atomic_cmp_set((uint32_t *)gp_lock, 0, 1)) {

#endif

sched_yield();

}

#endif

#if THREAD

++g_count1;

++g_count2;

#else

++(*(volatile uint32_t *)gp_count1);

++(*(volatile uint32_t *)gp_count2);

#endif

#if SPIN_LOCK

#if THREAD

g_lock = 0;

#else

*(uint32_t *)gp_lock = 0;

#endif /* THEAD */

#endif

}

#if SPIN_LOCK

#if !THREAD

shmdt(gp_lock);

#endif

#endif

return NULL;

}

int main(int argc, char *argv[])

{

// 创建共享内存

shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0600);

if (-1 == shmid) {

return -1;

}

#if THREAD

pthread_t t1 = 0, t2 = 0;

pthread_create(&t1, NULL, &thread_func, NULL);

pthread_create(&t2, NULL, &thread_func, NULL);

sleep(1);

g_continue = 0;

pthread_join(t1, NULL);

pthread_join(t2, NULL);

#else

#if SPIN_LOCK

gp_lock = shmat(shmid, 0, 0);

*(uint32_t *)gp_lock = 0;

#endif

gp_continue = ((char *)shmat(shmid, 0, 0)) + 4;

*(uint32_t *)gp_continue = 1;

gp_count1 = ((char *)shmat(shmid, 0, 0)) + 8;

*(uint32_t *)gp_count1 = 0;

gp_count2 = ((char *)shmat(shmid, 0, 0)) + 12;

*(uint32_t *)gp_count2 = 0;

switch (fork()) {

case 0:

break;

case -1:

exit(-1);

default:

{

int x = fork();

if (x > 0) {

sleep(1);

*(uint32_t *)gp_continue = 0;

wait(NULL);

shmdt(gp_continue);

(void)shmctl(shmid, IPC_RMID, 0);

exit(0);

}

}

}

thread_func(NULL);

#endif

fprintf(stderr,

"%u, %u\n",

#if THREAD

g_count1,

g_count2);

#else

*(volatile uint32_t *)gp_count1,

*(volatile uint32_t *)gp_count2);

#endif

return 0;

}

ps: 汇编代码源自nginx,CAS机制只能实现自旋锁,因为用户态无法挂起唤醒线程,可以借助futex实现互斥锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值