On Fri, Mar 5, 2021 at 12:03 PM Peter Oskolkov <posk@xxxxxxx> wrote: > > Hi André! > > On Thu, Mar 4, 2021 at 10:58 AM André Almeida <andrealmeid@xxxxxxxxxxxxx> wrote: > > > > Hi Peter, > > > > Às 02:44 de 04/03/21, Peter Oskolkov escreveu: > > > On Wed, Mar 3, 2021 at 5:22 PM André Almeida <andrealmeid@xxxxxxxxxxxxx> wrote: > > >> > > >> Hi, > > >> > > >> This patch series introduces the futex2 syscalls. > > >> > > >> * FAQ > > >> > > >> ** "And what's about FUTEX_64?" > > >> > > >> By supporting 64 bit futexes, the kernel structure for futex would > > >> need to have a 64 bit field for the value, and that could defeat one of > > >> the purposes of having different sized futexes in the first place: > > >> supporting smaller ones to decrease memory usage. This might be > > >> something that could be disabled for 32bit archs (and even for > > >> CONFIG_BASE_SMALL). > > >> > > >> Which use case would benefit for FUTEX_64? Does it worth the trade-offs? > > > > > > The ability to store a pointer value on 64bit platforms is an > > > important use case. > > > Imagine a simple producer/consumer scenario, with the producer updating > > > some shared memory data and waking the consumer. Storing the pointer > > > in the futex makes it so that only one shared memory location needs to be > > > accessed "atomically", etc. With two atomics synchronization becomes > > > more involved (= slower). > > > > > > > So the idea is to, instead of doing this: > > > > T1: > > atomic_set(&shm_addr, buffer_addr); > > atomic_set(&futex, 0); > > futex_wake(&futex, 1); > > > > T2: > > consume(shm_addr); > > > > To do that: > > > > T1: > > atomic_set(&futex, buffer_addr); > > futex_wake(&futex, 1); > > > > T2: > > consume(futex); > > > > Right? > > More like this: > > T1 (producer): > while (true) { > ptr = get_new_data(); > atomic_set(&futex, ptr); > futex_wake(&futex, 1); > } > > T1 (consumer): > some_data *prev = NULL; > while (true) { > futex_wait(&futex, prev); > some_data *next = atomic_get(&futex); > if (next == prev) continue; /* spurious wakeup */ > > consume_data(next); > prev = next; > } Or an even more complete example: T1 (producer): while (true) { next = get_new_data(); atomic_set(&futex, next); futex_wake(&futex, 1); /* wait for the consumer */ prev = next; do { next = atomic_get(&futex); futex_wait(&futex, prev); } while (next != NULL); } T2 (consumer): some_data *prev = NULL; while (true) { futex_wait(&futex, prev); some_data *next = atomic_get(&futex); if (next == prev) continue; /* spurious wakeup */ consume_data(next); prev = next; atomic_set(&futex, NULL); futex_wake(&futex, 1); /* signal we can consumer more */ } > > > > > > > I'll try to write a small test to see how the perf numbers looks like.