mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-10-27 06:31:23 +01:00
MEDIUM: ring: always allocate properly aligned ring structures
The rings were manually padded to place the various areas that compose them into different cache lines, provided that the allocator returned a cache-aligned address, which until now was not granted. By now switching to the aligned API we can finally have this guarantee and hope for more consistent ring performance between tests. Like previously the few carefully crafted THREAD_PAD() could simply be replaced by generic THREAD_ALIGN() that dictate the type's alignment. This was the last user of THREAD_PAD() by the way.
This commit is contained in:
parent
cfdab917fe
commit
a7f8693fa2
@ -130,11 +130,11 @@ struct ring_wait_cell {
|
|||||||
struct ring_storage {
|
struct ring_storage {
|
||||||
size_t size; // storage size
|
size_t size; // storage size
|
||||||
size_t rsvd; // header length (used for file-backed maps)
|
size_t rsvd; // header length (used for file-backed maps)
|
||||||
THREAD_PAD(64 - 2 * sizeof(size_t));
|
THREAD_ALIGN(64);
|
||||||
size_t tail; // storage tail
|
size_t tail; // storage tail
|
||||||
THREAD_PAD(64 - sizeof(size_t));
|
THREAD_ALIGN(64);
|
||||||
size_t head; // storage head
|
size_t head; // storage head
|
||||||
THREAD_PAD(64 - sizeof(size_t));
|
THREAD_ALIGN(64);
|
||||||
char area[0]; // storage area begins immediately here
|
char area[0]; // storage area begins immediately here
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,10 +148,9 @@ struct ring {
|
|||||||
uint waking; // indicates a thread is currently waking up readers
|
uint waking; // indicates a thread is currently waking up readers
|
||||||
|
|
||||||
/* keep the queue in a separate cache line below */
|
/* keep the queue in a separate cache line below */
|
||||||
THREAD_PAD(64 - 3*sizeof(void*) - 4*sizeof(int));
|
|
||||||
struct {
|
struct {
|
||||||
|
THREAD_ALIGN(64);
|
||||||
struct ring_wait_cell *ptr;
|
struct ring_wait_cell *ptr;
|
||||||
THREAD_PAD(64 - sizeof(void*));
|
|
||||||
} queue[RING_WAIT_QUEUES + 1]; // wait queue + 1 spacer
|
} queue[RING_WAIT_QUEUES + 1]; // wait queue + 1 spacer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
14
src/ring.c
14
src/ring.c
@ -83,12 +83,12 @@ struct ring *ring_make_from_area(void *area, size_t size, int reset)
|
|||||||
if (size < sizeof(*ring->storage) + 2)
|
if (size < sizeof(*ring->storage) + 2)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ring = malloc(sizeof(*ring));
|
ring = ha_aligned_alloc_typed(1, typeof(*ring));
|
||||||
if (!ring)
|
if (!ring)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!area)
|
if (!area)
|
||||||
area = malloc(size);
|
area = ha_aligned_alloc(__alignof__(*ring->storage), size);
|
||||||
else
|
else
|
||||||
flags |= RING_FL_MAPPED;
|
flags |= RING_FL_MAPPED;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ struct ring *ring_make_from_area(void *area, size_t size, int reset)
|
|||||||
ring->flags |= flags;
|
ring->flags |= flags;
|
||||||
return ring;
|
return ring;
|
||||||
fail:
|
fail:
|
||||||
free(ring);
|
ha_aligned_free(ring);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ struct ring *ring_resize(struct ring *ring, size_t size)
|
|||||||
return ring;
|
return ring;
|
||||||
|
|
||||||
old = ring->storage;
|
old = ring->storage;
|
||||||
new = malloc(size);
|
new = ha_aligned_alloc(__alignof__(*ring->storage), size);
|
||||||
if (!new)
|
if (!new)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ struct ring *ring_resize(struct ring *ring, size_t size)
|
|||||||
thread_release();
|
thread_release();
|
||||||
|
|
||||||
/* free the unused one */
|
/* free the unused one */
|
||||||
free(new);
|
ha_aligned_free(new);
|
||||||
return ring;
|
return ring;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +162,8 @@ void ring_free(struct ring *ring)
|
|||||||
|
|
||||||
/* make sure it was not allocated by ring_make_from_area */
|
/* make sure it was not allocated by ring_make_from_area */
|
||||||
if (!(ring->flags & RING_FL_MAPPED))
|
if (!(ring->flags & RING_FL_MAPPED))
|
||||||
free(ring->storage);
|
ha_aligned_free(ring->storage);
|
||||||
free(ring);
|
ha_aligned_free(ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tries to send <npfx> parts from <prefix> followed by <nmsg> parts from <msg>
|
/* Tries to send <npfx> parts from <prefix> followed by <nmsg> parts from <msg>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user