fix mirrored memory not working on linux

add mirrored memory unit test
This commit is contained in:
Andrew Kelley 2015-09-14 14:56:13 -07:00
parent 7e95d9f9c0
commit f52080a1fd
2 changed files with 52 additions and 3 deletions

View file

@ -668,26 +668,56 @@ int soundio_os_init_mirrored_memory(struct SoundIoOsMirroredMemory *mem, size_t
break; break;
} }
#else #else
char shm_path[] = "/dev/shm/soundio-XXXXXX";
char tmp_path[] = "/tmp/soundio-XXXXXX";
char *chosen_path;
int fd = mkstemp(shm_path);
if (fd < 0) {
fd = mkstemp(tmp_path);
if (fd < 0) {
return SoundIoErrorSystemResources;
} else {
chosen_path = tmp_path;
}
} else {
chosen_path = shm_path;
}
if (unlink(chosen_path)) {
close(fd);
return SoundIoErrorSystemResources;
}
if (ftruncate(fd, actual_capacity)) {
close(fd);
return SoundIoErrorSystemResources;
}
char *address = (char*)mmap(NULL, actual_capacity * 2, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); char *address = (char*)mmap(NULL, actual_capacity * 2, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (address == MAP_FAILED) if (address == MAP_FAILED)
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
char *other_address = (char*)mmap(address, actual_capacity, PROT_READ|PROT_WRITE, char *other_address = (char*)mmap(address, actual_capacity, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_FIXED|MAP_SHARED, -1, 0); MAP_FIXED|MAP_SHARED, fd, 0);
if (other_address != address) { if (other_address != address) {
munmap(address, 2 * actual_capacity); munmap(address, 2 * actual_capacity);
close(fd);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
other_address = (char*)mmap(address + actual_capacity, actual_capacity, other_address = (char*)mmap(address + actual_capacity, actual_capacity,
PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_FIXED|MAP_SHARED, -1, 0); PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0);
if (other_address != address + actual_capacity) { if (other_address != address + actual_capacity) {
munmap(address, 2 * actual_capacity); munmap(address, 2 * actual_capacity);
close(fd);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
mem->address = address; mem->address = address;
if (close(fd))
return SoundIoErrorSystemResources;
#endif #endif
mem->capacity = actual_capacity; mem->capacity = actual_capacity;

View file

@ -15,7 +15,7 @@ static inline void ok_or_panic(int err) {
} }
static void test_os_get_time(void) { static void test_os_get_time(void) {
soundio_os_init(); ok_or_panic(soundio_os_init());
double prev_time = soundio_os_get_time(); double prev_time = soundio_os_get_time();
for (int i = 0; i < 1000; i += 1) { for (int i = 0; i < 1000; i += 1) {
double time = soundio_os_get_time(); double time = soundio_os_get_time();
@ -165,6 +165,24 @@ static void test_ring_buffer_threaded(void) {
soundio_destroy(soundio); soundio_destroy(soundio);
} }
static void test_mirrored_memory(void) {
struct SoundIoOsMirroredMemory mem;
ok_or_panic(soundio_os_init());
static const int requested_bytes = 1024;
ok_or_panic(soundio_os_init_mirrored_memory(&mem, requested_bytes));
const int size_bytes = mem.capacity;
for (int i = 0; i < size_bytes; i += 1) {
mem.address[i] = rand() % CHAR_MAX;
}
for (int i = 0; i < size_bytes; i += 1) {
assert(mem.address[i] == mem.address[size_bytes+i]);
}
soundio_os_deinit_mirrored_memory(&mem);
}
struct Test { struct Test {
const char *name; const char *name;
void (*fn)(void); void (*fn)(void);
@ -175,6 +193,7 @@ static struct Test tests[] = {
{"create output stream", test_create_outstream}, {"create output stream", test_create_outstream},
{"ring buffer basic", test_ring_buffer_basic}, {"ring buffer basic", test_ring_buffer_basic},
{"ring buffer threaded", test_ring_buffer_threaded}, {"ring buffer threaded", test_ring_buffer_threaded},
{"mirrored memory", test_mirrored_memory},
{NULL, NULL}, {NULL, NULL},
}; };