/*
* ptw32_OLL_lock.c
*
* Description:
* This translation unit implements extended reader/writer queue-based locks.
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.au
*
* The current list of contributors is contained
* in the file CONTRIBUTORS included with the source
* code distribution. The list can also be seen at the
* following World Wide Web location:
* http://sources.redhat.com/pthreads-win32/contributors.html
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library in the file COPYING.LIB;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* About the OLL lock (Scalable Reader-Writer Lock):
*
* OLL locks are queue-based locks similar to the MCS queue lock, where the queue
* nodes are local to the thread but where reader threads can enter the critical
* section immediately without going through a central guard lock if there are
* already readers holding the lock.
*
* Covered by United States Patent Application 20100241774 (Oracle)
*/
#include "pthread.h"
#include "sched.h"
#include "implement.h"
/*
* C-SNZI support
*/
typedef union ptw32_oll_counter_t_ ptw32_oll_counter_t;
typedef struct ptw32_oll_snziRoot_t_ ptw32_oll_snziRoot_t;
typedef struct ptw32_oll_snziNode_t_ ptw32_oll_snziNode_t;
typedef union ptw32_oll_snziNodeOrRoot_t_ ptw32_oll_snziNodeOrRoot_t;
typedef struct ptw32_oll_queryResult_t_ ptw32_oll_queryResult_t;
typedef struct ptw32_oll_ticket_t_ ptw32_oll_ticket_t;
typedef struct ptw32_oll_csnzi_t_ ptw32_oll_csnzi_t;
enum
{
ptw32_archWidth = sizeof(size_t)*8,
ptw32_oll_countWidth = ptw32_archWidth-2
};
#define PTW32_OLL_MAXREADERS (((size_t)2<<(ptw32_oll_countWidth-1))-1)
union ptw32_oll_counter_t_
{
size_t word : ptw32_archWidth;
struct
{
/*
* This needs to be a single word
*
* ------------------------------------
* | STATE | ROOT | COUNT (readers) |
* ------------------------------------
* 63 / 31 62 / 30 61 / 29 .. 0
*/
size_t count : ptw32_oll_countWidth;
size_t root : 1; /* ROOT or NODE */
size_t state : 1; /* OPEN or CLOSED (root only) */
} internal;
};
struct ptw32_oll_snziRoot_t_
{
/*
* "counter" must be at same offset in both
* ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
*/
ptw32_oll_counter_t counter;
};
enum
{
ptw32_oll_snziRoot_open = 0,
ptw32_oll_snziRoot_closed = 1
};
enum
{
ptw32_oll_snzi_root = 0,
ptw32_oll_snzi_node = 1
};
/*
* Some common SNZI root whole-word states that can be used to set or compare
* root words with a single operation.
*/
ptw32_oll_snziRoot_t ptw32_oll_snziRoot_openAndZero = {.counter.internal.count = 0,
.counter.internal.root = ptw32_oll_snzi_root,
.counter.internal.state = ptw32_oll_snziRoot_open};
ptw32_oll_snziRoot_t ptw32_oll_snziRoot_closedAndZero = {.counter.internal.count = 0,
.counter.internal.root = ptw32_oll_snzi_root,
.counter.internal.state = ptw32_oll_snziRoot_closed};
struct ptw32_oll_queryResult_t_
{
BOOL nonZero;
BOOL open;
};
union ptw32_oll_snziNodeOrRoot_t_
{
ptw32_oll_snziRoot_t* rootPtr;
ptw32_oll_snziNode_t* nodePtr;
};
struct ptw32_oll_snziNode_t_
{
/* "counter" must be at same offset in both
* ptw32_oll_snziNode_t and ptw32_oll_snziRoot_t
*/
ptw32_oll_counter_t counter;
ptw32_oll_snziNodeOrRoot_t parentPtr;
};
struct ptw32_oll_ticket_t_
{
ptw32_oll_snziNodeOrRoot_t snziNodeOrRoot;
};
ptw32_oll_ticket_t ptw32_oll_ticket_null = {NULL};
struct ptw32_oll_csnzi_t_
{
ptw32_oll_snziRoot_t proxyRoot;
ptw32_oll_snziNode_t leafs[];
};
/*
* FOLL lock support
*/
typedef struct ptw32_foll_node_t_ ptw32_foll_node_t;
typedef struct ptw32_foll_local_t_ ptw32_foll_local_t;
typedef struct ptw32_foll_rwlock_t_ ptw32_foll_rwlock_t;
enum
{
ptw32_srwl_reader,
ptw32_srwl_writer
};
enum
{
ptw32_srwl_free,
ptw32_srwl_in_use
};
struct ptw32_foll_node_t_
{
ptw32_foll_node_t* qNextPtr;
ptw32_oll_csnzi_t* csnziPtr;
ptw32_foll_node_t* nextPtr;
int kind;
int allocState;
BOOL spin;
};
struct ptw32_foll_local_t_
{
ptw32_foll_node_t* rNodePtr; // Default read node. Immutable
ptw32_foll_node_t* wNodePtr; // Write node. Immutable.
ptw32_foll_node_t* departFromPtr; // List node we last arrived at.
ptw32_oll_ticket_t ticket; // C-SNZI ticket
};
struct ptw32_foll_rwlock_t_
{
ptw32_foll_node_t* tailPtr;
ptw32_foll_node_t* rNodesPtr; // Head of reader node
};
/*
* ShouldArriveAtTree() returns true if:
* the compare_exchange in Arrive() fails too often under read access; or
* ??
* Note that this is measured across all access to
* this lock, not just this attempt, so that highly
* read-contended locks will use C-SNZI. Lightly
* read-contended locks can reduce memory usage and some
* processing by using the root directly.
*/
BOOL
ptw32_oll_ShouldArriveAtTree()
{
return PTW32_FALSE;
}
size_t
ptw32_oll_GetLeafForThread()
{
return 0;
}
/*
* Only readers call ptw32_oll_Arrive()
*
* Checks whether the C-SNZI state is OPEN, and if so,
* increments the surplus of the C-SNZI by either directly
* arriving at the root node, or calling TreeArrive on one
* of the leaf nodes. Returns a ticket pointing to the node
* that was arrived at. If the state is CLOSED, makes no
* change and returns a ticket that contains no pointer.
*/
ptw32_oll_ticket_t
ptw32_oll_Arrive(ptw32_oll_csnzi_t* csnzi)
{
for (;;)
{
ptw32_oll_ticket_t ticket;
ptw32_oll_snziRoot_t oldProxy = csnzi->proxyRoot;
if (oldProxy.counter.internal.state != ptw32_oll_snziRoot_open)
{
ticket.snziNodeOrRoot.rootPtr = (ptw32_oll_snziRoot_t*)NULL;
return ticket;
}
if (!ptw32_oll_ShouldArriveAtTree())
{
ptw32_oll_snziRoot_t newProxy = oldProxy;
newProxy.counter.internal.count++;
if (PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE(
(PTW32_INTERLOCKED_SIZEPTR)&csnzi->proxyRoot.counter,
(PTW32_INTERLOCKED_SIZE)newProxy.counter.word,
(PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
== (PTW32_INTERLOCKED_SIZE)oldProxy.counter.word)
{
/* Exchange successful */
ticket.snziNodeOrRoot.rootPtr = &csnzi->proxyRoot;
return ticket;
}
}
else
{
ptw32_oll_snziNode_t* leafPtr = &csnzi->leafs[ptw32_oll_GetLeafForThread()];
ticket.snziNodeOrRoot.nodePtr = (ptw32_oll_TreeArrive(leafPtr) ? leafPtr : (ptw32_oll_snziNode_t*)NULL);
return ticket;
}
}
}
/*
* Decrements the C-SNZI surplus. Returns false iff the
* resulting state
pthreads-w32-2.9.1-release.zip


《pthreads-w32-2.9.1-release:Windows平台上的POSIX线程库解析》 在Windows操作系统上开发跨平台的软件时,我们常常会遇到一个问题:如何在不支持原生POSIX线程(pthreads)的环境中实现与Unix/Linux系统兼容的多线程编程。这时,pthreads-w32就成为了关键的解决方案。pthreads-w32是一个开源项目,它为Windows提供了符合POSIX标准的线程API,使开发者可以在Windows系统上使用与Unix/Linux系统相同的线程接口进行编程。 标题“pthreads-w32-2.9.1-release.zip”表明这是pthreads-w32的一个版本发布,版本号为2.9.1,以ZIP格式打包。描述中的内容重复了标题,暗示这个压缩包包含了pthreads-w32的2.9.1版本的所有文件。 标签“pthreads-w32-2.9”可能代表的是一个系列或者版本范围,说明这个版本属于2.9大版本的范畴。这通常意味着它继承了之前版本的主要功能,并可能在此基础上进行了优化或添加了新的特性。 压缩包内的文件包括: 1. LISENCE.txt:这是开源软件的标准组成部分,通常包含了软件的许可协议信息,详细规定了用户可以如何使用、修改和分发该软件。 2. pthreads-w32-2.9.1-release:这是一个文件夹,很可能包含了pthreads-w32的具体实现和库文件,包括头文件、动态链接库(DLL)和静态库(LIB)等,供开发者在项目中引用。 3. Pre-built.2:这可能是一个预编译的库文件集合,提供不同配置下的编译结果,方便用户根据自己的系统环境选择合适的版本。 4. QueueUserAPCEx:这可能是一个扩展的API函数,用于向其他线程的异步过程调用(APC)队列中添加函数调用,这是Windows线程间通信的一种方式。 5. pthreads.2:这可能是pthreads API的文档或者手册页,提供了详细的接口说明和技术指南,帮助开发者理解和使用pthreads-w32提供的功能。 pthreads-w32的核心功能是实现了POSIX线程标准,如pthread_create、pthread_join、pthread_mutex_init等,使得Windows开发者可以使用熟悉的线程管理API进行多线程编程。此外,它还提供了线程同步机制,如互斥量、条件变量、信号量等,以及线程属性设置、线程局部存储等功能。通过pthreads-w32,开发者可以在Windows平台上无缝地移植使用pthreads的Unix/Linux代码,极大地提高了跨平台开发的效率。 总结来说,pthreads-w32-2.9.1-release.zip是一个为Windows系统提供POSIX线程支持的开源库,包含了一系列必要的库文件、文档和许可协议,使得开发者能够在Windows环境中使用与Unix/Linux相一致的线程编程接口。这对于那些需要在不同操作系统上保持代码一致性的项目来说,无疑是一个极其重要的工具。





































































































- 1
- 2
- 3
- 4
- 5
- 6
- 10















- 粉丝: 15w+
- 资源: 235
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- cotParam-C语言资源
- 基于大型语言模型的多智能体协作框架MetaGPT的设计与应用:提升复杂软件开发效率
- 【多媒体交互】Unity Kinect实现UI控件的点击
- 信创项目:DB2到达梦数据库的迁移方案详解及关键技术要点
- hikyuu-C++资源
- hutool-Java资源
- DrissionPage-Python资源
- 逆向工程,用于plc软件逆推,可进行反汇编和加密软件解密
- 全国走失儿童数据.zip
- 汽车之家最终数据源.xlsx
- Maven 是一个强大的 Java 项目构建工具,主要用于项目依赖管理、构建和部署 以下是 Maven 的下载、安装与配置的详细步骤: - ### **一、Maven 下载** 1. **访
- Screenshot_20250325_172319_me_ele_EMagexActivity.jpg
- 在 Linux 系统中,命令行是进行各种操作的强大工具 以下是一些常用的 Linux 命令及其基本用法: ### 文件和目录操作 - **ls**: 列出目录内容 ```bash ls
- STM32入门实践 温湿度检测 蓝牙数据传输 stm32f103c8t6 本科课设
- 虚拟化环境中基于Virsh的RHEL8服务器虚拟机部署与管理实训指导
- treescan-4.72-1.el8.x64-86.rpm.tar.gz



评论0