因为在X86上long会被分割为两个int进行操作, 那么Interlocked.Increment的实现成为了一个问题。

在一番搜索后未发现有现成的文章解释这个问题,于是我就动手分析了。

这篇是笔记,不会做过多的解释。

首先重现环境是 .Net Core 2.0 Windows (x86) Binaries, 下载可以到 https://www.microsoft.com/net/download/core#/sdk

重现的代码如下

using System;
using System.Threading; namespace x86program
{
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
Console.WriteLine("Hello World!");
Console.ReadLine();
long a = 0x1234567887564321;
Console.WriteLine(Interlocked.Increment(ref a));
}
}
}

需要的工具:

Visual Studio 2017 15.3 RTM

OllyDbg 1.1 (or 2.0)

首先下载了x86版的dotnet后,解压然后在命令行运行

F:\dotnet-sdk-2.0.0-win-x86\x86program>..\dotnet.exe run

运行后使用Visual Studio打开项目然后"附加到进程", 成功后在下图中的地方下断点

然后命令行回车, 可以触发此断点, 我们可以看到 Interlocked.Increment 调用了 0x76A7CA0 处的函数, 传入参数只有一个, 就是指向long变量的指针

之后在Visual Studio中取消附加, 然后使用ollydbg的Attach, 成功后在 0x76A7CA0 下断点

这个函数调用了函数 0x7428BE0, 传入了分割为两个int的long (1), ecx仍然指向原来的long变量

函数 0x7428BE0 是一个JIT桩(Stub), 第一次调用会触发JIT编译, 第二次调用会跳到JIT编译结果

JIT编译后的实现就在 0x3410F40 处,这里的就是 Interlocked.Increment(ref long) 的实现

我们可以看到这个实现使用了x86的CMPXCHG8B指令,如果出现long变量的值被其他线程修改,会检测出来并重试添加

当然,不是所有x86的CPU都支持CMPXCHG8B指令, 但至少可以运行.Net Core的CPU都会支持此指令, 也就是说实现 atomic long 不需要semaphore

http://www.geoffchappell.com/studies/windows/km/cpu/cx8.htm

上面的代码是Debug下编译得到的, Release下同样需要调用一个helper函数, 内部的逻辑是一样的

x64位上的 Interlocked.Increment(ref long) 就很简单了, 可以使用现成的指令 lock xadd

分析到此为止

=================================================================================

微软最近发布了新的JIT文档,比原来的文档要容易理解很多,有兴趣的可以去围观:

https://github.com/dotnet/coreclr/blob/master/Documentation/botr/ryujit-tutorial.md

下一篇CoreCLR源码探索会讲解JIT是如何实现的,但是还需要最少一个月的时间,有兴趣的请耐心等待。

.Net Core在X86上实现Interlocked.Increment(ref long)的方式的更多相关文章

  1. 多线程相关Interlocked.Increment问题

    今天群里有人问到如下代码打印出来的东西为什么不是连续得,所以有大神解释了原因.在这过程中遇到了些奇怪的情况 static void Main(string[] args) { for (int i = ...

  2. Interlocked.Increment 方法 和Interlocked.Decrement 方法作用

    Interlocked.Increment 方法:让++成为原子操作:Interlocked.Decrement 方法让--成为原子操作.什么叫原子操作呢.就是不会被别人打断,因为C#中的一个语句,编 ...

  3. Interlocked.Increment()函数详解 (转载)

    原文地址 class Program { static object lockObj = new object(); ; ; //假设要处理的数据源 , ).ToList(); static void ...

  4. 在ASP.NET Core Web API上使用Swagger提供API文档

    我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的API文档功能.当设置IISExpress的默认启动路由到Swagger的API文档页 ...

  5. win2008server R2 x64 部署.net core到IIS上出现【Failed to load the dll from [C:\Program Files\dotnet\host\fxr\1.0.1\hostfxr.dll], HRESULT: 0x80070057】错误

    win2008server R2 x64 部署.net core到IIS上出现[Failed to load the dll from [C:\Program Files\dotnet\host\fx ...

  6. Core Web API上使用Swagger提供API文档

    在ASP.NET Core Web API上使用Swagger提供API文档   我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的AP ...

  7. .net core版 文件上传/ 支持批量上传,拖拽以及预览,bootstrap fileinput上传文件

    asp.net mvc请移步 mvc文件上传支持批量上传,拖拽以及预览,文件内容校验 本篇内容主要解决.net core中文件上传的问题  开发环境:ubuntu+vscode 1.导入所需要的包:n ...

  8. .Net Core 图片文件上传下载

    当下.Net Core项目可是如雨后春笋一般发展起来,作为.Net大军中的一员,我热忱地拥抱了.Net Core并且积极使用其进行业务的开发,我们先介绍下.Net Core项目下实现文件上传下载接口. ...

  9. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

    早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...

随机推荐

  1. [转载] 文件锁(Filelock)与锁定映射文件部分内容

    转载自http://jiangzhengjun.iteye.com/blog/517677 文件锁 JDK 1.4引入了文件加锁机制,允许我们同步访问一个共享文件,不过,竞争同一文件的两个线程有可能在 ...

  2. 四、VueJs 填坑日记之搭建Axios接口请求工具

    上一章,我们认识了项目的目录结构,以及对项目的目录结构做了一些调整,已经能把项目重新跑起来了.今天我们来搭建api接口调用工具Axios.Vue本身是不支持ajax调用的,如果你需要这些功能就需要安装 ...

  3. mybatis逆向工程之生成文件解释

    一.mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException ...

  4. C#winform程序安装在默认路径提示权限不足的问题

    这个需要以管理员身份运行即可.在program.cs里面修改即可也可以在别的地方,如:C# 编程中可以使程序自动使用管理员身份运行,也就是我们常常看到一些程序的图标上会冒出个盾牌.方法:在源码的Pro ...

  5. 2723:不吉利日期-poj

    2723:不吉利日期 总时间限制:  1000ms 内存限制:  65536kB 描述 在国外,每月的13号和每周的星期5都是不吉利的.特别是当13号那天恰好是星期5时,更不吉利.已知某年的一月一日是 ...

  6. git使用(上)-----基本的方法

    git应该是一项必须要掌握的工具.先简述它和SVN的区别 SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活 ...

  7. pytesseract使用

    1.安装pip install pytesseract 2.安装tesseract-ocr,下载地址:https://github.com/UB-Mannheim/tesseract/wiki,我安装 ...

  8. qt学习教程1.qt开发环境搭建

    qt学习教程1.qt开发环境搭建 首先下载qt 下载地址:http://download.qt.io/archive/qt/ 此教程使用的版本为5.1.1 下载好后,打开安装包,然后点下一步 选择一个 ...

  9. Cannot load browser "PhantomJS": it is not registered! Perhaps you are missing some plugin? 测试安装遇到的BUG

    安装了半天phantomjs就是安装不好,后面想了个死办法,http://phantomjs.org/download.html这个网址下先去下载好 phantomjs-2.1.1-windows.z ...

  10. 乌龟棋dp

    传送门题目:https://www.luogu.org/problem/show?pid=1541 其实这道题想到了就很简单,但很难想到用思维的dp,这非常少见. 看到每张牌不超过40张,这数据范围就 ...