lock
- #ifndef lock_h
- #define lock_h
- #include <stdint.h>
- #include <string.h>
- #include "mydef.h"
- #include "now.h"
- #define debug_lock 1
- typedef struct {
- intptr_t lck;
- uintptr_t tid;
- uintptr_t nr;
- #if debug_lock
- const char* file;
- uintptr_t line;
- #endif
- } lock_t;
- #define lock_initial {0}
- #define lock_initial_locked {1, 0, 1}
- static __attribute__((unused)) lock_t lock_val = lock_initial;
- #if (debug_lock == 2)
- #define locktrace_begin() uintptr_t tms = now();
- #define lock_backtrace(lkp) \
- do { \
- uintptr_t current = now(); \
- if (tms == 0) { \
- tms = current; \
- } \
- \
- if (current > tms + 3000) { \
- tms = current - 2000; \
- logmsg("locktrace: %d %s:%d\n", (int) lkp->lck, lkp->file, (int) lkp->line); \
- } \
- } while (0)
- #else
- #define locktrace_begin() (void) 0
- #define lock_backtrace(x) (void) 0
- #endif
- #if debug_lock
- #define log_lock(ptr, l, f) do {ptr->line = l; ptr->file = f;} while (0)
- #define log_unlock(ptr) do {ptr->line = -1; ptr->file = "";} while (0)
- #else
- #define log_lock(ptr, l, f) (void) (0)
- #define log_unlock(ptr) (void) (0)
- #endif
- #ifdef __linux__
- #ifndef _GNU_SOURCE
- #define _GNU_SOURCE
- #endif
- #define my_lock(lkp, re) \
- do { \
- lock_t* ptr = lkp; \
- if (!__sync_bool_compare_and_swap(&ptr->lck, 0, 1)) { \
- if (ptr->lck == 2) { \
- syscall(__NR_futex, &ptr->lck, FUTEX_WAIT, 2, NULL, NULL, 0); \
- } \
- \
- locktrace_begin(); \
- while (0 != __sync_lock_test_and_set(&ptr->lck, 2)) { \
- syscall(__NR_futex, &ptr->lck, FUTEX_WAIT, 2, NULL, NULL, 0); \
- lock_backtrace(ptr); \
- } \
- } \
- my_assert2(ptr->lck != 0, "lck = %d", ptr->lck); \
- my_assert2(ptr->nr == 0, "lck = %d, nr = %d, %d@%s", ptr->lck, ptr->nr, ptr->line, ptr->file); \
- log_lock(ptr, __LINE__, __FILE__); \
- \
- my_assert(ptr->tid == 0); \
- if (re) { \
- ptr->tid = systid(); \
- } \
- ++ptr->nr; \
- } while (0)
- #define unlock(lkp) \
- do { \
- lock_t* ptr = lkp; \
- my_assert2(ptr->lck != 0, "lck = %d, nr = %d", ptr->lck, ptr->nr); \
- --ptr->nr; \
- wmb(); \
- if (ptr->nr > 0) { \
- my_assert2(ptr->tid != 0, "tid != 0, ptr->nr = %d, lck = %d, %d@%s", ptr->nr, ptr->lck, ptr->line, ptr->file); \
- } else { \
- ptr->tid = 0; \
- /* wmb(); */ \
- log_unlock(ptr); \
- if (2 == __sync_lock_test_and_set(&ptr->lck, 0)) { \
- while (-1 == syscall(__NR_futex, &ptr->lck, FUTEX_WAKE, 1, NULL, NULL, 0)); \
- } \
- } \
- } while (0)
- #else
- #define my_lock(lkp, re) \
- do { \
- lock_t* ptr = lkp; \
- locktrace_begin(); \
- while (!__sync_bool_compare_and_swap((void **) &ptr->lck, (void *) 0, (void *) 1)) { \
- sched_yield(); \
- lock_backtrace(ptr); \
- } \
- log_lock(ptr, __LINE__, __FILE__); \
- \
- my_assert(ptr->tid == 0); \
- if (re) { \
- ptr->tid = systid(); \
- } \
- ++ptr->nr; \
- } while (0)
- #define unlock(lkp) \
- do { \
- lock_t* ptr = lkp; \
- my_assert(ptr->lck != 0); \
- --ptr->nr; \
- wmb(); \
- if (ptr->nr > 0) { \
- my_assert(ptr->tid != 0); \
- } else { \
- ptr->tid = 0; \
- /* wmb(); */ \
- log_unlock(ptr); \
- ptr->lck = 0; \
- } \
- } while (0)
- #endif
- #define lock(lkp) my_lock(lkp, 0)
- #define relock(lkp) \
- do { \
- lock_t* ptr = lkp; \
- /* this rmb() is here to assure to see ptr->tid = 0 in unlock */ \
- /* if thread exit after unlock(), then another thread is spwaned with same tid */ \
- /* on another cpu core and then call lock_recursive. */ \
- /* all the above happens so quickly that the other cpu core does not see ptr->tid = 0 */ \
- /* it is so impossible to happen that I comment the "correct" implemention. */ \
- /* rmb(); */ \
- \
- if (ptr->tid == systid()) { \
- /* if true, it's same thread, event in another cpu core, no mb() is needed. */ \
- ++ptr->nr; \
- } else { \
- my_lock(lkp, 1); \
- } \
- } while (0)
- static __attribute__((unused)) inline intptr_t my_try_lock(lock_t* lkp, uintptr_t re, uintptr_t line, const char* file)
- {
- if (!__sync_bool_compare_and_swap((void **) &((lkp)->lck), (void *) 0, (void *) 1)) {
- return -1;
- }
- log_lock(lkp, line, file);
- my_assert(lkp->tid == 0);
- if (re) {
- lkp->tid = systid();
- }
- ++lkp->nr;
- return 0;
- }
- #define try_lock(lkp) my_try_lock(lkp, 0, __LINE__, __FILE__)
- #define retry_lock(lkp) my_try_lock(lkp, 1, __LINE__, __FILE__)
- typedef struct {
- intptr_t nr;
- } rwlock_t;
- #define read_write_max 8000
- #define rw_lock_initial {read_write_max}
- static __attribute__((unused)) rwlock_t rw_lock_val = rw_lock_initial;
- #define read_write_lock(lckp, val) \
- do { \
- rwlock_t* lck = lckp; \
- do { \
- intptr_t n = __sync_sub_and_fetch(&lck->nr, val); \
- if (n >= 0) { \
- break; \
- } \
- __sync_add_and_fetch(&lck->nr, val); \
- sched_yield(); \
- } while (1); \
- } while (0)
- #define read_write_unlock(lckp, val) \
- do { \
- rwlock_t* lck = lckp; \
- __sync_add_and_fetch(&lck->nr, val); \
- } while (0)
- #define read_lock(lckp) read_write_lock(lckp, 1)
- #define write_lock(lckp) read_write_lock(lckp, read_write_max)
- #define read_unlock(lckp) read_write_unlock(lckp, 1)
- #define write_unlock(lckp) read_write_unlock(lckp, read_write_max)
- #endif
lock的更多相关文章
- C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent
看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex S ...
- 多线程同步工具——Lock
本文原创,转载请注明出处. 参考文章: <"JUC锁"03之 公平锁(一)> <"JUC锁"03之 公平锁(二)> 锁分独占锁与共享锁, ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
- InnoDB:Lock & Transaction
InnoDB 是一个支持事务的Engine,要保证事务ACID,必然会用到Lock.就像在Java编程一下,要保证数据的线程安全性,必然会用到Lock.了解Lock,Transaction可以帮助sq ...
- 使用四元数解决万向节锁(Gimbal Lock)问题
问题 使用四元数可以解决万向节锁的问题,但是我在实际使用中出现问题:我设计了一个程序,显示一个三维物体,用户可以输入绕zyx三个轴进行旋转的指令,物体进行相应的转动. 由于用户输入的是绕三个轴旋转的角 ...
- 万向节锁(Gimbal Lock)的理解
[TOC] 结论 我直接抛出结论: Gimbal Lock 产生的原因不是欧拉角也不是旋转顺序,而是我們的思维方式和程序的执行逻辑没有对应,也就是说是我们的观念导致这个情况的发生. 他人解释 首先我们 ...
- 在多线程编程中lock(string){...}隐藏的机关
常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...
- 谈谈 Lock
上来先看MSDN关于lock的叙述: lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 下面的示例包含一个 lock 语句. lock 关键字可确保当一 ...
- LOCK TABLES和UNLOCK TABLES与Transactions的交互
LOCK TABLES对事务不安全,并且在试图锁定表之前隐式提交任何活动事务. UNLOCK TABLES只有在LOCK TABLES已经获取到表锁时,会隐式提交任何活动事务.对于下面的一组语句,UN ...
- SQL 性能调优中可参考的几类Lock Wait
在我们的系统出现性能问题时,往往避不开调查各种类型 Lock Wait,如Row Lock Wait.Page Lock Wait.Page IO Latch Wait等.从中找出可能的异常等待,为性 ...
随机推荐
- intel82599在centos6.5下编译安装
.intel驱动下载地址:https://sourceforge.net/projects/e1000/files/ixgbe%20stable/ .编译安装步骤 yum install kernel ...
- sharepoint 增删改查
前端提交 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="MeetingOneW ...
- Creating Dialogs
#ifndef DIALOG_H #define DIALOG_H #include <QtWidgets> //#include <QDialog> //#include & ...
- JavaScript 中的对象
JavaScript 中的对象 在 JavaScript 中,对象是数据(变量),拥有属性和方法. JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等. 访问对象的属性 访 ...
- 已禁用对分布式事务管理器(MSDTC)的网络访问的解决方法之一
C# ASP.NET项目提示上述错误,在代码中使用分布式事务提示添加或修改到数据库的时候.添加数据到数据库时,不会设置实体类的主键字段.
- RealSense开发-Session和SenseManager的几种创建方法
从Intel RealSense 的SDK文档对其架构(如图1所示)的始描述可知,Session是SDK应用的主控模块,必须在所有模块操作之前创建,并且在所有模块注销后最后注销.SenseManage ...
- python用来压缩目录的脚本
import zipfile,os,sys def zip_dir(dirname, zipfilename): filelist = [] if os.path.isfile(dirname): f ...
- 如何正确使用$_SERVER['DOCUMENT_ROOT']识别该路径的文件
echo $_SERVER['DOCUMENT_ROOT']; 这时输出当前文件所在的路径 D:/phpStudy/WWW/study/php&mysql $_SERVER['DOCUMENT ...
- Javascript 数组常用操作方法
一.数组 Array 1.创建数组 /* 构造函数 */ var arr1 = new Array(); //创建一个空数组 var arr1 = new Array(5); //创建指定长度数组(数 ...
- Linux系统移植(1) ------搭建交叉编译环境
本人的开发环境是ubuntu12.05的64版本,运行在11.00的虚拟机上.首先说明为什么需要搭建交叉编译环境.我们知道,我们的开发一般在PC机上,是基于X86架构的,而我们的开发板却是基于ARM架 ...