因为在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. JavaScript基本知识点整理(超实用)

      絮叨絮叨                   今天给大家分享一下这两天自己整理的JavaScript部分的笔记,下面都是我觉得比较常用的,希望能帮助到大家! 1. 导入JS的三种方式 ①在HTML ...

  2. 准备冲锋 golang入坑系列

    史前摘要: 本来想写读前必读,但连续几篇博文都写读前必读,感觉就没有了新意. 所以换成史前摘要,反正是一个意思. 此摘要的目的仍然是提醒点击而来的同学,本系列最新文章在这里.放到博客园的目的是为了方便 ...

  3. JavaScript学习笔记(十)——高阶函数之map,reduce,filter,sort

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  4. formData实现图片上传

    前言 在 上一篇 已经实现了图片预览,那么如何上传图片呢?有两种思路: 1.将图片转化为dataURL(base64),这样就成为了一串字符串,再传到服务端.不过这样缺点很多,数据量比转换之前增加1/ ...

  5. 机器学习算法--Perceptron(感知机)算法

    感知机: 假设输入空间是\(\chi\subseteq R^n\),输出空间是\(\gamma =\left( +1,-1\right)\).输入\(\chi\in X\)表示实例的特征向量,对应于输 ...

  6. 数据结构 集合_集合(数学)抽象数据类型的C语言实现

    链表是实现集合的一种理想的方式.将List以typedef的方式重命名为Set.这样做能保留链表简洁的特性,还能使集合具有了一些多态的特性. 使用这种方法的最大好处就是可以使用list_next来遍历 ...

  7. 【微软大法好】VS Tools for AI全攻略(3)

    接着上文,现在我们需要一种穷人的方法来搭建好Azure虚拟机. 思路很简单,因为AI组件的原理其实是传送了script文件和命令上去,那么我们这个虚拟机只要做好了所有的配置,那么我们就可以将它当作深度 ...

  8. SQL语言(二) java怎样连接操作数据库中的数据

    import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.S ...

  9. ajax处理级联访问数据库显示

    首先创建简单的html页面,写出如下代码: 静态页相关代码: js代码:

  10. OCPC(Optimized Cost per Click)机制

    背景 在线广告中,广告按照CPM排序,排在前面的广告竞争有限广告位(截断).其中,CPM=bid*pctr.注GSP二价计费的,按照下一位bid计费.适当调整bid,可以提高竞价的排名,从而获得展现的 ...