Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit a201c20

Browse files
vmggitster
authored andcommitted
ewah: support platforms that require aligned reads
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]>
1 parent c3d8da5 commit a201c20

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

ewah/ewah_io.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,23 +112,38 @@ int ewah_serialize(struct ewah_bitmap *self, int fd)
112112

113113
int ewah_read_mmap(struct ewah_bitmap *self, void *map, size_t len)
114114
{
115-
uint32_t *read32 = map;
116-
eword_t *read64;
117-
size_t i;
115+
uint8_t *ptr = map;
116+
117+
self->bit_size = get_be32(ptr);
118+
ptr += sizeof(uint32_t);
119+
120+
self->buffer_size = self->alloc_size = get_be32(ptr);
121+
ptr += sizeof(uint32_t);
118122

119-
self->bit_size = ntohl(*read32++);
120-
self->buffer_size = self->alloc_size = ntohl(*read32++);
121123
self->buffer = ewah_realloc(self->buffer,
122124
self->alloc_size * sizeof(eword_t));
123125

124126
if (!self->buffer)
125127
return -1;
126128

127-
for (i = 0, read64 = (void *)read32; i < self->buffer_size; ++i)
128-
self->buffer[i] = ntohll(*read64++);
129+
/*
130+
* Copy the raw data for the bitmap as a whole chunk;
131+
* if we're in a little-endian platform, we'll perform
132+
* the endianness conversion in a separate pass to ensure
133+
* we're loading 8-byte aligned words.
134+
*/
135+
memcpy(self->buffer, ptr, self->buffer_size * sizeof(uint64_t));
136+
ptr += self->buffer_size * sizeof(uint64_t);
137+
138+
#if __BYTE_ORDER != __BIG_ENDIAN
139+
{
140+
size_t i;
141+
for (i = 0; i < self->buffer_size; ++i)
142+
self->buffer[i] = ntohll(self->buffer[i]);
143+
}
144+
#endif
129145

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

133148
return (3 * 4) + (self->buffer_size * 8);
134149
}

0 commit comments

Comments
 (0)