For example, functions like futex_wake
/futex_wait
, epoll_ctl
/epoll_wait
, pthread_create
provide acquire/release semantics. That's to say, I made some changes before calling futex_wake
, and then the woken thread always sees the changes.
My question is
- does the read/write to
eventfd
offer acquire/release semantics? - is there any documents about this? I have checked the man page and did not find the answer about 1.
see blow code as an example:
initial:
int g_atomic_val = 0;
int evfd = eventfd();
int64_t w_cnt = 1, r_cnt;
thread1:
/* set some data, then write eventfd */
g_atomic_val = 1;
write(evfd, &w_cnt, sizeof(w_cnt));
thread2:
for (;;) {
/* polling event fd */
poll(evfd);
read(evfd, &r_cnt, sizeof(r_cnt));
/* Does g_atomic_val always equals to 1? */
assert(g_atomic_val == 1);
}
getpid(2)
used to only invoke an actual system call the first time; it would cache the result and return it directly on subsequent calls (invalidating onfork()
etc). Sogetpid()
might only execute one load instruction, with no particular memory ordering, and then return. – Readyrelaxed
– Pegsem_post
can't block but we really, really hope that it contains a release barrier. – Readyread
norwrite
can block, but a write/read pair is expected to be usable for synchronization. Orsem_post
versussem_getvalue
. – Readyread
should be based on a futex and a shared buffer... – Verbalizewrite
says things like "Writes can be serialized with respect to other reads and writes. If a read() of file data can be proven (by any means) to occur after a write() of the data, it must reflect that write(), even if the calls are made by different processes." [...] – Readyread
is also required to immediately observe writes made viammap
, and vice versa. So anmmap
is a mapping of that same shared buffer. – Ready