Skip to content

Instantly share code, notes, and snippets.

@nbkolchin
Created March 24, 2020 19:14
Show Gist options
  • Save nbkolchin/067fb7adc45f2a084915a1ec17ed5e61 to your computer and use it in GitHub Desktop.
Save nbkolchin/067fb7adc45f2a084915a1ec17ed5e61 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <pthread.h>
#define BOOL bool
#define FALSE false
#define SIZE_T size_t
#define _ASSERTE(...) assert(__VA_ARGS__)
static pthread_mutex_t flushProcessWriteBuffersMutex;
static int* s_helperPage = 0;
size_t GetVirtualPageSize()
{
return getpagesize();
}
BOOL InitializeFlushProcessWriteBuffers()
{
// _ASSERTE(s_helperPage == 0);
// _ASSERTE(s_flushUsingMemBarrier == 0);
s_helperPage = static_cast<int*>(mmap(0, GetVirtualPageSize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
if(s_helperPage == MAP_FAILED)
{
printf("mmap failed\n");
return FALSE;
}
// Verify that the s_helperPage is really aligned to the GetVirtualPageSize()
_ASSERTE((((SIZE_T)s_helperPage) & (GetVirtualPageSize() - 1)) == 0);
// Locking the page ensures that it stays in memory during the two mprotect
// calls in the FlushProcessWriteBuffers below. If the page was unmapped between
// those calls, they would not have the expected effect of generating IPI.
int status = mlock(s_helperPage, GetVirtualPageSize());
if (status != 0)
{
printf("mlock failed: %s (%zu)\n", strerror(errno), GetVirtualPageSize());
return FALSE;
}
status = pthread_mutex_init(&flushProcessWriteBuffersMutex, NULL);
if (status != 0)
{
printf("mutex failed\n");
munlock(s_helperPage, GetVirtualPageSize());
}
return status == 0;
}
int main()
{
printf("%s\n", InitializeFlushProcessWriteBuffers() ? "OK" : "FAILURE");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment