On 18/07/2018 17:41, Denis Plotnikov wrote:
> +static void ram_page_buffer_decrease_used(void)
> +{
> + qemu_event_reset(&ram_state->page_buffer.used_decreased);
> + atomic_dec(&ram_state->page_buffer.used);
> + qemu_event_set(&ram_state->page_buffer.used_decreased);
As Peter noted, only the qemu_event_set is needed here, while...
> +}
> +
> +static void ram_page_buffer_increase_used_wait(void)
> +{
> + int used, *used_ptr;
> + RAMState *rs = ram_state;
> + used_ptr = &rs->page_buffer.used;
> + do {
> + used = atomic_read(used_ptr);
> + if (rs->page_buffer.capacity > used) {
> + if (atomic_cmpxchg(used_ptr, used, used + 1) == used) {
> + return;
> + } else {
> + continue;
> + }
> + } else {
> + qemu_event_wait(&rs->page_buffer.used_decreased);
> + }
> + } while (true);
... the right idiom for using qemu_event_wait is this:
if test condition
reset
if test condition
wait
So something like
for(;;) {
used = atomic_read(used_ptr);
if (rs->page_buffer.capacity <= used) {
qemu_event_reset(&rs->page_buffer.used_decreased);
used = atomic_read(used_ptr);
if (rs->page_buffer.capacity <= used) {
qemu_event_wait(&rs->page_buffer.used_decreased);
continue;
}
}
if (atomic_cmpxchg(used_ptr, used, used + 1) == used) {
return;
}
}
Note that there must be a single thread doing the above. Otherwise, you
have to use mutex and condvar.
Paolo