Revision ef36fa14 exec.c
b/exec.c | ||
---|---|---|
904 | 904 |
return fs.f_bsize; |
905 | 905 |
} |
906 | 906 |
|
907 |
static sigjmp_buf sigjump; |
|
908 |
|
|
909 |
static void sigbus_handler(int signal) |
|
910 |
{ |
|
911 |
siglongjmp(sigjump, 1); |
|
912 |
} |
|
913 |
|
|
907 | 914 |
static void *file_ram_alloc(RAMBlock *block, |
908 | 915 |
ram_addr_t memory, |
909 | 916 |
const char *path) |
... | ... | |
913 | 920 |
char *c; |
914 | 921 |
void *area; |
915 | 922 |
int fd; |
916 |
#ifdef MAP_POPULATE |
|
917 |
int flags; |
|
918 |
#endif |
|
919 | 923 |
unsigned long hpagesize; |
920 | 924 |
|
921 | 925 |
hpagesize = gethugepagesize(path); |
... | ... | |
963 | 967 |
if (ftruncate(fd, memory)) |
964 | 968 |
perror("ftruncate"); |
965 | 969 |
|
966 |
#ifdef MAP_POPULATE |
|
967 |
/* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case |
|
968 |
* MAP_PRIVATE is requested. For mem_prealloc we mmap as MAP_SHARED |
|
969 |
* to sidestep this quirk. |
|
970 |
*/ |
|
971 |
flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE; |
|
972 |
area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0); |
|
973 |
#else |
|
974 | 970 |
area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); |
975 |
#endif |
|
976 | 971 |
if (area == MAP_FAILED) { |
977 | 972 |
perror("file_ram_alloc: can't mmap RAM pages"); |
978 | 973 |
close(fd); |
979 | 974 |
return (NULL); |
980 | 975 |
} |
976 |
|
|
977 |
if (mem_prealloc) { |
|
978 |
int ret, i; |
|
979 |
struct sigaction act, oldact; |
|
980 |
sigset_t set, oldset; |
|
981 |
|
|
982 |
memset(&act, 0, sizeof(act)); |
|
983 |
act.sa_handler = &sigbus_handler; |
|
984 |
act.sa_flags = 0; |
|
985 |
|
|
986 |
ret = sigaction(SIGBUS, &act, &oldact); |
|
987 |
if (ret) { |
|
988 |
perror("file_ram_alloc: failed to install signal handler"); |
|
989 |
exit(1); |
|
990 |
} |
|
991 |
|
|
992 |
/* unblock SIGBUS */ |
|
993 |
sigemptyset(&set); |
|
994 |
sigaddset(&set, SIGBUS); |
|
995 |
pthread_sigmask(SIG_UNBLOCK, &set, &oldset); |
|
996 |
|
|
997 |
if (sigsetjmp(sigjump, 1)) { |
|
998 |
fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n"); |
|
999 |
exit(1); |
|
1000 |
} |
|
1001 |
|
|
1002 |
/* MAP_POPULATE silently ignores failures */ |
|
1003 |
for (i = 0; i < (memory/hpagesize)-1; i++) { |
|
1004 |
memset(area + (hpagesize*i), 0, 1); |
|
1005 |
} |
|
1006 |
|
|
1007 |
ret = sigaction(SIGBUS, &oldact, NULL); |
|
1008 |
if (ret) { |
|
1009 |
perror("file_ram_alloc: failed to reinstall signal handler"); |
|
1010 |
exit(1); |
|
1011 |
} |
|
1012 |
|
|
1013 |
pthread_sigmask(SIG_SETMASK, &oldset, NULL); |
|
1014 |
} |
|
1015 |
|
|
981 | 1016 |
block->fd = fd; |
982 | 1017 |
return area; |
983 | 1018 |
} |
Also available in: Unified diff