为什么将函数参数标记为易失性

发布于 2025-01-06 23:26:17 字数 852 浏览 2 评论 0原文

我目前正在阅读 PostgreSql 代码。以下是缓冲区管理器的摘录:

static void WaitIO(volatile BufferDesc *buf);
static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,

我知道 volatile 关键字通常用于设备驱动程序和嵌入式系统中。有关键字的解释。

当在类型定义中使用关键字 volatile 时,它​​向编译器指示应如何处理变量。主要是告诉编译器,由于程序或当前执行行外部的操作,变量的值可能随时发生变化。 (来源)

那么为什么某些函数参数被声明为易失性的呢?我不希望 DMA 改变指针位置。那么这里会发生什么呢?

I am currently reading the PostgreSql code. Here is an excerpt from the buffer manager:

static void WaitIO(volatile BufferDesc *buf);
static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,

I know the volatile keyword is usually used for device drivers and in embedded systems. There is an explanation of the keyword.

When the keyword volatile is used in the type definition it is giving an indication to the compiler on how it should handle the variable. Primarily it is telling the compiler that the value of the variable may change at any time as a result of actions external to the program or current line of execution.
(Source)

So why are certain function arguments declared as volatile? I don't expect that DMA changes the pointer location. So what happens here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一袭白衣梦中忆 2025-01-13 23:26:17

volatile BufferDesc *buf 表示 buf指向的数据是易失性的,而不是 buf 包含的指针是不稳定的。 (这将是 BufferDesc * 易失性 buf 。)

来自 您链接到的页面

另一方面,如果你有一个指针变量,其地址本身是易失性的,但指向的内存不是易失性的,那么我们有:

int * 易失性 x;

重新回答您问题的这一部分:

那么为什么某些函数参数被声明为易失性的呢?

大概是因为它指向的数据可能会以编译器不一定知道的方式发生变化。 volatile 关键字的作用是防止编译器应用假设数据不会以它不知道的方式更改的优化。

volatile BufferDesc *buf means that the data that buf points to is volatile, not that the pointer contained by buf is volatile. (That would be BufferDesc * volatile buf.)

From the page you linked to:

On the other hand, if you have a pointer variable where the address itself was volatile but the memory pointed to was not then we have:

int * volatile x;

Re this part of your question:

So why are certain function arguments declared as volatile?

Presumably because the data it points to can change in a way that the compiler wouldn't necessarily know about. The volatile keyword is there to prevent the compiler applying optimizations that assume the data doesn't change in ways it doesn't know about.

不气馁 2025-01-13 23:26:17

我不希望 DMA 改变指针位置。

不是地点,而是内容。这正是它的目的......

I don't expect that DMA changes the pointer location.

Not the location, but maybe the content. And that's exactly what it is about...

耳根太软 2025-01-13 23:26:17

访问文件时,数据库实现不依赖操作系统缓冲区和缓存。他们更喜欢实现自己的缓存系统并直接访问物理磁盘上的文件,以解决可靠性问题:数据必须刷新到物理磁盘。 (它们使用 O_DIRECT 选项来执行对物理磁盘的直接访问。)

您向我们展示的 3 个函数让我想到了来自磁盘的数据的异步处理。 (StartBufferIO()、TerminationBufferIO() 等)。老实说,我不确定它们的目的是什么,但是根据我对数据库实现和这些函数名称的了解,我想说缓冲区内容可能会被“磁盘”本身使用磁盘上文件中的数据进行修改(或任何设备),因此需要标记为易失性

这个假设与您对易失性关键字通常用于什么的通常解释相结合:设备驱动程序。

Databases implementation does not rely on the OS buffers&caches when accessing files. They prefer to implement they own cache system and get direct access to the file on the physical disk, for reliability issues: data MUST to be flushed to the physical disk. (They use the O_DIRECT option to perform direct access to physical disk.)

The 3 functions you are showing us make me think of asynchronous handling of data coming from the disk. (StartBufferIO(), TerminatedBufferIO() and so on). Honestly I am not sure of what is their purpose, but based on what I know about databases implementation, and those function names, I would say that the buffer content might be modified by the "disk" itself with data from the file on the disk (or whatever device), and therefore needs to be flaged as volatile.

This hypothesis joins your usual interpretation of what the volatile keyword is usually used for: device drivers.

相权↑美人 2025-01-13 23:26:17

DMA 并不是使用“易失性”的唯一原因。它对于多线程和共享内存应用程序也很有用,其中另一个线程可能会更改此代码引用的内存。我确信 PostgreSql 是多线程的,所以这可能是这里使用 volatile 的原因。

DMA isn't the only reason to use "volatile". It's also useful for multithreaded and shared memory applications, where another thread may change memory referenced by this code. I'm sure that PostgreSql is multi-threaded, so this is a likely reason why volatile is being used here.

手心的海 2025-01-13 23:26:17

编译器在优化时通常做的一件事是删除死代码,因此,如果您对一个从未读取过的变量执行一些操作,并且其结果无用,编译器可能只会删除它,以及删除影响它的其余操作。当您调试代码或执行某种基准测试时,这种行为可能会非常烦人。如果您将变量声明为易失性,您会警告编译器它可能会被外部库或程序使用,以及该关键字可能具有的其他含义。那么它就不应该将其视为死代码。

One thing a compiler usually does when optimising is removing dead code, so if you do some operations with a variable that its never read neither and its result is useless compiler will probably just remove it, as well as removing the rest of operations that affects it. That behaviour can be very annoying when your debug a code ore your are performing some kind of benchamrks. If you declare as volatile a variable you alert the compiler it could be used by external libraries or programs, among other implications the keyword may have. Then it should never treat it as dead code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文