Skip to content

Commit

Permalink
Opt, 使用cpuid重新实现GetCurrentProcessorNumber,让XP下STL的多线程调度正常工作
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed May 9, 2024
1 parent 202abd6 commit 9439a08
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
44 changes: 24 additions & 20 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# YY-Thunks - 让兼容 Windows 更轻松
![license](https://img.shields.io/github/license/Chuyu-Team/YY-Thunks)
![downloads](https://img.shields.io/github/downloads/Chuyu-Team/YY-Thunks/total)
![contributors](https://img.shields.io/github/contributors-anon/Chuyu-Team/YY-Thunks)
![release](https://img.shields.io/github/v/release/Chuyu-Team/YY-Thunks?include_prereleases)
![nuget](https://img.shields.io/nuget/vpre/YY-Thunks)
[![license](https://img.shields.io/github/license/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/blob/master/LICENSE)
[![downloads](https://img.shields.io/github/downloads/Chuyu-Team/YY-Thunks/total)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![contributors](https://img.shields.io/github/contributors-anon/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/graphs/contributors)
[![release](https://img.shields.io/github/v/release/Chuyu-Team/YY-Thunks?include_prereleases)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![nuget](https://img.shields.io/nuget/vpre/YY-Thunks)](https://www.nuget.org/packages/YY-Thunks)
[![Build&Test](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml/badge.svg)](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml)

## 关于 YY-Thunks
## 1. 关于 YY-Thunks

众所周知,从 Windows 的每次更新又会新增大量 API,这使得兼容不同版本的 Windows
需要花费很大精力。导致现在大量开源项目已经不再兼容一些早期的 Windows 版本,比如
Expand All @@ -19,32 +19,38 @@ YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编

[ [鸭船交流群 633710173](https://shang.qq.com/wpa/qunwpa?idkey=21d51d8ad1d77b99ea9544b399e080ec347ca6a1bc04267fb59cebf22644a42a) ]

### 原理
### 1.1. 原理

使用 `LoadLibrary` 以及 `GetProcAddress` 动态加载 API,不存在时做出补偿措施,
最大限度模拟原始 API 行为,让你的程序正常运行。

### 亮点
### 1.2. 亮点

* 更快!更安全!`鸭船`内建2级缓存以及按需加载机制,同时自动加密所有函数指针,
防止内存爆破攻击。最大程度减少不需要和不必要的 `LoadLibrary` 以及
`GetProcAddress` 调用以及潜在安全风险。
* 轻松兼容 Windows XP,让你安心专注于业务逻辑。
* 完全开源且广泛接受用户意见,希望大家能踊跃的创建 PR,为`鸭船`添砖加瓦。

## 使用方法
## 2. 使用方法

大家可以在以下方案中任选一种,但是我们优先推荐 NuGet 方案。

### NuGet(推荐)
大家可以在以下方案中任选一种,但是我们优先推荐 NuGet 方案,因为NuGet采用傻瓜式设计,使用更便捷。

### 2.1. NuGet(推荐)
#### 2.1.1. C++项目
1. 项目右键 “管理 NuGet 程序包”。
2. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
3. 项目右键 - 属性 - YY-Thunks 中,自行调整YY-Thunks等级,允许 Windows 2000,
Windows XP 以及 Windows Vista(默认)。
4. 重新编译代码

### 手工配置
#### 2.1.2. .NET Native AOT项目
1.`TargetFramework`添加`Windows`系统平台,比如修改为`net8.0-windows`或者`net9.0-windows`
2. 项目右键 `管理 NuGet 程序包`
3. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
4. 默认兼容到Windows Vista(默认),如果需要兼容Windows XP可以将`WindowsSupportedOSPlatformVersion`调整为`5.1`

### 2.2. 手工配置

1. 下载 [YY-Thunks-Binary](https://github.com/Chuyu-Team/YY-Thunks/releases)
然后解压到你的工程目录。
Expand All @@ -56,28 +62,26 @@ YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编
> 温馨提示:如果需要兼容 Vista,【所需的最低版本】无需修改,但是【附加依赖项】请选择
`objs\$(PlatformShortName)\YY_Thunks_for_Vista.obj`

> 如果不清楚链接器相关配置,建议使用NuGet通道,它自动配置相关设置,降低使用门槛。
## 兼容性
## 3. 兼容性

### 支持的编译器
### 3.1. 支持的编译器

全平台ABI兼容。

* 所有Visual Studio版本均支持
(比如:VC6.0、VS2008、VS2010、VS2015、VS2017、VS2019、VS2022等等)。
* 所有运行库模式均支持(比如:`/MD``/MT``/MDd``/MTd`)。

### SDK版本要求
### 3.2. SDK版本要求
至少需要SDK 6.0(VS2008默认附带)

> 温馨提示:VC6.0、VS2005用户请注意,由于这些编译器默认附带的SDK版本太低。请先将SDK升级到6.0或者更高版本,然后再使用YY-Thunks,否则将发生链接失败!
高版本的SDK不影响对老系统的兼容性,请坐和放宽,安心升级。

### Thunks 清单
### 3.3. Thunks 清单

请参阅 [ThunksList.md](ThunksList.md)

## 更新日志
## 4. 更新日志

请参阅 [releases 更新日志](https://github.com/Chuyu-Team/YY-Thunks/releases)
18 changes: 9 additions & 9 deletions ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

此表展示了YY-Thunks(鸭船)可以解决的函数不存在问题,欢迎大家扩充!

> 开头带`*`的函数并不建议使用,仅用于编译通过处理,如果使用可能导致老版本系统无法充分发挥性能
> 开头带`*`的函数并不建议使用,存在一些较大负面影响,仅用于编译通过处理,具体负面影响可参考注释内容
## api-ms-win-core-path-l1-1-0.dll
| 函数 | Fallback
Expand Down Expand Up @@ -227,14 +227,14 @@
| WaitOnAddress | 不存在时,调用NtWaitForKeyedEvent。警告,此函数请勿跨模块使用!!!
| WakeByAddressSingle | 不存在时,调用NtReleaseKeyedEvent。警告,此函数请勿跨模块使用!!!
| WakeByAddressAll | 不存在时,调用NtReleaseKeyedEvent。警告,此函数请勿跨模块使用!!!
| *GetCurrentProcessorNumber | 不存在时,返回0
| *GetCurrentProcessorNumberEx | 不存在时,调用GetCurrentProcessorNumber。
| *GetNumaNodeProcessorMask | 不存在时,假定所有CPU都在当前Numa。
| *GetNumaNodeProcessorMaskEx | 不存在时,调用GetNumaNodeProcessorMask。
| *GetThreadGroupAffinity | 不存在时,调用NtQueryInformationThread。
| *SetThreadGroupAffinity | 不存在时,调用SetThreadAffinityMask。
| *CancelIoEx | 不存在时,调用CancelIo会把此句柄的所有IO操作取消掉!)。
| *CancelSynchronousIo | 不存在时,仅返回失败。
| GetCurrentProcessorNumber | 不存在时,调用cpuid
| GetCurrentProcessorNumberEx | 不存在时,调用GetCurrentProcessorNumber。
| GetNumaNodeProcessorMask | 不存在时,假定所有CPU都在当前Numa。
| GetNumaNodeProcessorMaskEx | 不存在时,调用GetNumaNodeProcessorMask。
| GetThreadGroupAffinity | 不存在时,调用NtQueryInformationThread。
| SetThreadGroupAffinity | 不存在时,调用SetThreadAffinityMask。
| *CancelIoEx | 不存在时,调用CancelIo。警告,会把此句柄的所有IO操作取消掉!
| *CancelSynchronousIo | 不存在时,仅返回失败。警告,实际无法取消!
| OpenFileById | 不存在时,调用NtCreateFile。
| CreateSymbolicLinkW(A) | 不存在时,返回FALSE,并设置 LastError = ERROR_INVALID_FUNCTION。
| ReOpenFile | 不存在时,调用NtCreateFile。
Expand Down
21 changes: 17 additions & 4 deletions src/Thunks/api-ms-win-core-processthreads.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,27 @@ namespace YY
VOID
)
{
if (auto pGetCurrentProcessorNumber = try_get_GetCurrentProcessorNumber())
if (const auto _pfnGetCurrentProcessorNumber = try_get_GetCurrentProcessorNumber())
{
return pGetCurrentProcessorNumber();
return _pfnGetCurrentProcessorNumber();
}
else
{
//如果不支持此接口,那么假定是单核
return 0;
// Reference: https://www.cs.tcd.ie/Jeremy.Jones/GetCurrentProcessorNumberXP.htm
//
// The GetCurrentProcessorNumber() function is not available in XP.
// Here is a VC++ version of the function that works with Windows XP on Intel x86 single, hyperthreaded, multicore
// and multi-socket systems. It makes use of the APIC ID returned by the CPUID instruction.
// This is in the range 0 .. N-1, where N is the number of logical CPUs.

__asm
{
mov eax, 1
cpuid
shr ebx, 24
// eax 返回值
mov eax, ebx
}
}
}
#endif
Expand Down

0 comments on commit 9439a08

Please sign in to comment.