.Net Core在X86上实现Interlocked.Increment(ref long)的方式
来源:互联网 发布:cat linux 指定行 编辑:程序博客网 时间:2024/05/29 10:13
因为在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)的方式
- 在.NET Core 上运行的 WordPress
- 在.NET Core 上运行的 WordPress
- 在.NET Core 上运行的 WordPress
- 在.NET Core 上运行的 WordPress
- OpenSolaris系统调用在x86系统上的实现
- RAS 在 x86 上的应用及 Linux 实现
- Spinlock在ARM及X86平台上的实现
- Spinlock在ARM及X86平台上的实现
- 在IIS上部署你的ASP.NET Core项目
- asp.net core在linux上的部署调试
- Interlocked 系列函数的实现
- System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)的问题
- Interlocked.Increment 方法 和Interlocked.Decrement 方法作用
- ASP.NET Core部署在IIS上
- .net core 搭载在 iis上
- Linux在X86上的虚拟内存管理
- Linux在X86上的虚拟内存管理
- Netty:实现同步发送并接收消息的一种方式
- LaTex:Markdown数学公式录入
- c语言原生实现MD5 不含c++的任何api
- jQuery access()方法解析
- 欢迎使用CSDN-markdown编辑器
- .Net Core在X86上实现Interlocked.Increment(ref long)的方式
- FIDO协议(fast identity online,快速身份识别在线联盟)
- 4.断路器Hystrix
- java 后台把数据以图片的形式传到前台
- webStorm报错Import declarations are not supported by current JavaScript version
- 单向访问
- 【Android开发笔记】自定义表格控件
- 何为SQL Server
- Spring IOC