作者:54打工仔i_858 | 来源:互联网 | 2022-12-21 17:49
以下代码loop出自NGINX,稍微修改的。atomic_lock.h1#pragmaonce2#ifndef_atomic_lock_h_include_3#define_a
以下代码loop出自NGINX,稍微修改的。
"atomic_lock.h"
1 #pragma once
2 #ifndef _atomic_lock_h_include_
3 #define _atomic_lock_h_include_
4
5 #define spin_num (2048)
6
7 #ifdef _MSC_VER
8
9 #include
10
11 #define cpu_pause() _mm_pause()
12 #define thread_yield() SwitchToThread()
13
14 __forceinline int compare_and_swap(long volatile *des, long out, long set)
15 {
16 InterlockedCompareExchange(des, set, out);
17 return *des == set;
18 }
19
20 #endif
21
22 #ifdef __GNUC__
23
24 #include
25
26 #define cpu_pause() __asm__ ("pause")
27 #define thread_yield() sched_yield()
28
29 #if defined(__INTEL_COMPILER) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))
30 #define USE_BUILTINS
31 #endif
32
33 static inline int compare_and_swap(volatile long* x, long oldval, long newval) {
34 #ifdef USE_BUILTINS
35 return __sync_bool_compare_and_swap(x, oldval, newval);
36 #elif defined(__i386__)
37 char result;
38 asm volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
39 return result;
40 #elif defined(__x86_64__)
41 char result;
42 asm volatile ("lock; cmpxchgq %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
43 return result;
44 #else
45 #error architecture not supported and gcc too old.
46 #endif
47 }
48
49 #endif
50
51 typedef struct {
52 volatile long lock;
53 } app_atomic_lock_t;
54
55
56 int app_atomic_trylock(app_atomic_lock_t* lt, long value);
57
58 void app_atomic_lock(app_atomic_lock_t* lt, long value);
59
60 void app_atomic_unlock(app_atomic_lock_t* lt, long value);
61 #endif
"atomic_lock.c"
1 #include "atomic_lock.h"
2
3 int app_atomic_trylock(app_atomic_lock_t * lt, long value)
4 {
5 return (lt->lock == 0 &&
6 compare_and_swap(<->lock, 0, value)); 8 }
9
10 void app_atomic_lock(app_atomic_lock_t * lt, long value)
11 {
12 u_int n, i;
13
14 for (;; ) {
15
16 if (lt->lock == 0 && compare_and_swap(<->lock, 0, value)) {
17 return;
18 }
19 for (n = 1; n 1
) {
20 21 for (i =
0; i
) {
22 cpu_pause();
23 }
24
25 if (lt->lock == 0 && compare_and_swap(<->lock, 0, value)) {
26 return;
27 }
28 }
29
30 thread_yield();
31 }
32 }
33
34 void app_atomic_unlock(app_atomic_lock_t * lt, long value)
35 {
36 compare_and_swap(<->lock, value, 0);
37 }
#include "atomic_lock.h"
app_atomic_lock_t lock;
volatile int value;
void* th_fun(void *arg)
{
int i;
for (i = 0; i <10000; i++){
app_atomic_lock(&lock, 100);
value++;
app_atomic_unlock(&lock, 100);
}
return NULL;
}
int main()
{
lock.lock = 0;
pthread_t th1, th2;
pthread_create(&th1, NULL, th_fun, NULL);
pthread_create(&th2, NULL, th_fun, NULL);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
printf("%d\n", value);
return 0;
}
cas在loop抢占的时候,会大量消耗cpu,在x86指令集下,可以用pause指令来减少loop的消耗。
cas锁在极高并发时候,会有非常大的帮助,相反,抢占时间过长,则千万不要用cas无锁。