this implementation is rather heavy-weight, but it's the first solution i've found that's actually correct. all waiters actually wait twice at the barrier so that they can synchronize exit, and they hold a "vm lock" that prevents changes to virtual memory mappings (and blocks pthread_barrier_destroy) until all waiters are finished inspecting the barrier. thus, it is safe for any thread to destroy and/or unmap the barrier's memory as soon as pthread_barrier_wait returns, without further synchronization.
21 lines
374 B
C
21 lines
374 B
C
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
#include "syscall.h"
|
|
#include "libc.h"
|
|
|
|
static void dummy1(int x) { }
|
|
static void dummy0(void) { }
|
|
weak_alias(dummy1, __vm_lock);
|
|
weak_alias(dummy0, __vm_unlock);
|
|
|
|
int __munmap(void *start, size_t len)
|
|
{
|
|
int ret;
|
|
__vm_lock(-1);
|
|
ret = syscall(SYS_munmap, start, len);
|
|
__vm_unlock();
|
|
return ret;
|
|
}
|
|
|
|
weak_alias(__munmap, munmap);
|