Skip to content

Commit

Permalink
ewah: support platforms that require aligned reads
Browse files Browse the repository at this point in the history
The caller may hand us an unaligned buffer (e.g., because it
is an mmap of a file with many ewah bitmaps). On some
platforms (like SPARC) this can cause a bus error. We can
fix it with a combination of get_be32 and moving the data
into an aligned buffer (which we would do anyway, but we can
move it before fixing the endianness).

Signed-off-by: Vicent Marti <[email protected]>
Signed-off-by: Jeff King <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
vmg authored and gitster committed Jan 23, 2014
1 parent c3d8da5 commit a201c20
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions ewah/ewah_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,38 @@ int ewah_serialize(struct ewah_bitmap *self, int fd)

int ewah_read_mmap(struct ewah_bitmap *self, void *map, size_t len)
{
uint32_t *read32 = map;
eword_t *read64;
size_t i;
uint8_t *ptr = map;

self->bit_size = get_be32(ptr);
ptr += sizeof(uint32_t);

self->buffer_size = self->alloc_size = get_be32(ptr);
ptr += sizeof(uint32_t);

self->bit_size = ntohl(*read32++);
self->buffer_size = self->alloc_size = ntohl(*read32++);
self->buffer = ewah_realloc(self->buffer,
self->alloc_size * sizeof(eword_t));

if (!self->buffer)
return -1;

for (i = 0, read64 = (void *)read32; i < self->buffer_size; ++i)
self->buffer[i] = ntohll(*read64++);
/*
* Copy the raw data for the bitmap as a whole chunk;
* if we're in a little-endian platform, we'll perform
* the endianness conversion in a separate pass to ensure
* we're loading 8-byte aligned words.
*/
memcpy(self->buffer, ptr, self->buffer_size * sizeof(uint64_t));
ptr += self->buffer_size * sizeof(uint64_t);

#if __BYTE_ORDER != __BIG_ENDIAN
{
size_t i;
for (i = 0; i < self->buffer_size; ++i)
self->buffer[i] = ntohll(self->buffer[i]);
}
#endif

read32 = (void *)read64;
self->rlw = self->buffer + ntohl(*read32++);
self->rlw = self->buffer + get_be32(ptr);

return (3 * 4) + (self->buffer_size * 8);
}
Expand Down

0 comments on commit a201c20

Please sign in to comment.