I have the below code where I'm intentionally creating a page fault in one of the threads in file.c
util.c
#include "util.h"
// to use as a fence() instruction
extern inline __attribute__((always_inline))
CYCLES rdtscp(void) {
CYCLES cycles;
asm volatile ("rdtscp" : "=a" (cycles));
return cycles;
}
// initialize address
void init_ram_address(char* FILE_NAME){
char *filename = FILE_NAME;
int fd = open(filename, O_RDWR);
if(fd == -1) {
printf("Could not open file .\n");
exit(0);
}
void *file_address = mmap(NULL, DEFAULT_FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
ram_address = (int *) file_address;
}
// initialize address
void init_disk_address(char* FILE_NAME){
char *filename = FILE_NAME;
int fd = open(filename, O_RDWR);
if(fd == -1) {
printf("Could not open file .\n");
exit(0);
}
void *file_address = mmap(NULL, DEFAULT_FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
disk_address = (int *) file_address;
}
file.c
#include "util.h"
void *f1();
void *f2();
pthread_barrier_t barrier;
pthread_mutex_t mutex;
int main(int argc, char **argv)
{
pthread_t t1, t2;
// in ram
init_ram_address(RAM_FILE_NAME);
// in disk
init_disk_address(DISK_FILE_NAME);
pthread_create(&t1, NULL, &f1, NULL);
pthread_create(&t2, NULL, &f2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
void *f1()
{
rdtscp();
int load = *(ram_address);
rdtscp();
printf("Expecting this to be run first.\n");
}
void *f2()
{
rdtscp();
int load = *(disk_address);
rdtscp();
printf("Expecting this to be run second.\n");
}
I've used rdtscp()
in the above code for fencing purposes (to ensure that the print statement get executed only after the load operation is done).
Since t2
will incur a page fault, I expect t1
to finish executing its print statement first.
To run both the threads on the same core, I run taskset -c 10 ./file
.
I see that t2
prints its statement before t1
. What could be the reason for this?