struct ring_storage {
size_t size; // storage size
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
- THREAD_PAD(64 - sizeof(size_t));
+ THREAD_ALIGN(64);
size_t head; // storage head
- THREAD_PAD(64 - sizeof(size_t));
+ THREAD_ALIGN(64);
char area[0]; // storage area begins immediately here
};
uint waking; // indicates a thread is currently waking up readers
/* keep the queue in a separate cache line below */
- THREAD_PAD(64 - 3*sizeof(void*) - 4*sizeof(int));
struct {
+ THREAD_ALIGN(64);
struct ring_wait_cell *ptr;
- THREAD_PAD(64 - sizeof(void*));
} queue[RING_WAIT_QUEUES + 1]; // wait queue + 1 spacer
};
if (size < sizeof(*ring->storage) + 2)
return NULL;
- ring = malloc(sizeof(*ring));
+ ring = ha_aligned_alloc_typed(1, typeof(*ring));
if (!ring)
goto fail;
if (!area)
- area = malloc(size);
+ area = ha_aligned_alloc(__alignof__(*ring->storage), size);
else
flags |= RING_FL_MAPPED;
ring->flags |= flags;
return ring;
fail:
- free(ring);
+ ha_aligned_free(ring);
return NULL;
}
return ring;
old = ring->storage;
- new = malloc(size);
+ new = ha_aligned_alloc(__alignof__(*ring->storage), size);
if (!new)
return NULL;
thread_release();
/* free the unused one */
- free(new);
+ ha_aligned_free(new);
return ring;
}
/* make sure it was not allocated by ring_make_from_area */
if (!(ring->flags & RING_FL_MAPPED))
- free(ring->storage);
- free(ring);
+ ha_aligned_free(ring->storage);
+ ha_aligned_free(ring);
}
/* Tries to send <npfx> parts from <prefix> followed by <nmsg> parts from <msg>