mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MEDIUM: move the ring's lock to only protect the readers list
Now the lock is only taken around the readers list. With careful ordering of writes to head/tail, the ring remains protected. The perf is a bit better, though (1.54M msg/s vs 1.4M at 48T on a 3rd gen EPYC, and 5.4M vs 5.3M for a 3C6T setup).
This commit is contained in:
parent
eb3d5f464d
commit
3cdd3d27a8
12
src/ring.c
12
src/ring.c
@ -245,9 +245,7 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz
|
|||||||
pl_wait_unlock_long(&ring->storage->tail, RING_TAIL_LOCK);
|
pl_wait_unlock_long(&ring->storage->tail, RING_TAIL_LOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
HA_RWLOCK_WRLOCK(RING_LOCK, &ring->lock);
|
head_ofs = HA_ATOMIC_LOAD(&ring->storage->head);
|
||||||
|
|
||||||
head_ofs = ring->storage->head;
|
|
||||||
|
|
||||||
/* this is the byte before tail, it contains the users count */
|
/* this is the byte before tail, it contains the users count */
|
||||||
lock_ptr = (uint8_t*)ring_area + (tail_ofs > 0 ? tail_ofs - 1 : ring_size - 1);
|
lock_ptr = (uint8_t*)ring_area + (tail_ofs > 0 ? tail_ofs - 1 : ring_size - 1);
|
||||||
@ -329,11 +327,12 @@ ssize_t ring_write(struct ring *ring, size_t maxlen, const struct ist pfx[], siz
|
|||||||
|
|
||||||
/* notify potential readers */
|
/* notify potential readers */
|
||||||
if (sent) {
|
if (sent) {
|
||||||
|
HA_RWLOCK_RDLOCK(RING_LOCK, &ring->lock);
|
||||||
list_for_each_entry(appctx, &ring->waiters, wait_entry)
|
list_for_each_entry(appctx, &ring->waiters, wait_entry)
|
||||||
appctx_wakeup(appctx);
|
appctx_wakeup(appctx);
|
||||||
|
HA_RWLOCK_RDUNLOCK(RING_LOCK, &ring->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
HA_RWLOCK_WRUNLOCK(RING_LOCK, &ring->lock);
|
|
||||||
leave:
|
leave:
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
@ -435,10 +434,8 @@ int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t
|
|||||||
ring_area = (uint8_t *)ring->storage->area;
|
ring_area = (uint8_t *)ring->storage->area;
|
||||||
ring_size = ring->storage->size;
|
ring_size = ring->storage->size;
|
||||||
|
|
||||||
HA_RWLOCK_RDLOCK(RING_LOCK, &ring->lock);
|
|
||||||
|
|
||||||
head_ofs = ring_head(ring);
|
|
||||||
tail_ofs = ring_tail(ring);
|
tail_ofs = ring_tail(ring);
|
||||||
|
head_ofs = HA_ATOMIC_LOAD(&ring->storage->head);
|
||||||
|
|
||||||
/* explanation for the initialization below: it would be better to do
|
/* explanation for the initialization below: it would be better to do
|
||||||
* this in the parsing function but this would occasionally result in
|
* this in the parsing function but this would occasionally result in
|
||||||
@ -528,7 +525,6 @@ int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t
|
|||||||
if (last_ofs_ptr)
|
if (last_ofs_ptr)
|
||||||
*last_ofs_ptr = tail_ofs;
|
*last_ofs_ptr = tail_ofs;
|
||||||
*ofs_ptr = head_ofs;
|
*ofs_ptr = head_ofs;
|
||||||
HA_RWLOCK_RDUNLOCK(RING_LOCK, &ring->lock);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user