X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=osdep.c;h=f2a69d9a7172c0e56c8598c8a37be119ef662a37;hb=b195775fef3c221ff04e3091005e16c5745bf3c8;hp=087a5c2185a3dad5f255ec54d91fe762a8c825e8;hpb=d2bfb39ad220a6431e366bdff72353b09f60e3db;p=qemu diff --git a/osdep.c b/osdep.c index 087a5c2..f2a69d9 100644 --- a/osdep.c +++ b/osdep.c @@ -273,6 +273,14 @@ void *get_mmap_addr(unsigned long size) #else +#ifdef _WIN32 +#include +#elif defined(_BSD) +#include +#else +#include +#endif + int qemu_write(int fd, const void *buf, size_t n) { int ret; @@ -298,6 +306,127 @@ void *qemu_malloc(size_t size) return malloc(size); } +#if defined(_WIN32) + +void *qemu_vmalloc(size_t size) +{ + /* FIXME: this is not exactly optimal solution since VirtualAlloc + has 64Kb granularity, but at least it guarantees us that the + memory is page aligned. */ + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); +} + +void qemu_vfree(void *ptr) +{ + VirtualFree(ptr, 0, MEM_RELEASE); +} + +#elif defined(USE_KQEMU) + +#include +#include +#include + +void *qemu_vmalloc(size_t size) +{ + static int phys_ram_fd = -1; + static int phys_ram_size = 0; + const char *tmpdir; + char phys_ram_file[1024]; + void *ptr; + struct statfs stfs; + + if (phys_ram_fd < 0) { + tmpdir = getenv("QEMU_TMPDIR"); + if (!tmpdir) + tmpdir = "/dev/shm"; + if (statfs(tmpdir, &stfs) == 0) { + int64_t free_space; + int ram_mb; + + extern int ram_size; + free_space = (int64_t)stfs.f_bavail * stfs.f_bsize; + if ((ram_size + 8192 * 1024) >= free_space) { + ram_mb = (ram_size / (1024 * 1024)); + fprintf(stderr, + "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n", + tmpdir, ram_mb); + if (strcmp(tmpdir, "/dev/shm") == 0) { + fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n" + "umount /dev/shm\n" + "mount -t tmpfs -o size=%dm none /dev/shm\n", + ram_mb + 16); + } else { + fprintf(stderr, + "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n" + "QEMU_TMPDIR environment variable to set another directory where the QEMU\n" + "temporary RAM file will be opened.\n"); + } + exit(1); + } + } + snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", + tmpdir); + if (mkstemp(phys_ram_file) < 0) { + fprintf(stderr, + "warning: could not create temporary file in '%s'.\n" + "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n" + "Using '/tmp' as fallback.\n", + tmpdir); + snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", + "/tmp"); + if (mkstemp(phys_ram_file) < 0) { + fprintf(stderr, "Could not create temporary memory file '%s'\n", + phys_ram_file); + exit(1); + } + } + phys_ram_fd = open(phys_ram_file, O_CREAT | O_TRUNC | O_RDWR, 0600); + if (phys_ram_fd < 0) { + fprintf(stderr, "Could not open temporary memory file '%s'\n", + phys_ram_file); + exit(1); + } + unlink(phys_ram_file); + } + size = (size + 4095) & ~4095; + ftruncate(phys_ram_fd, phys_ram_size + size); + ptr = mmap(NULL, + size, + PROT_WRITE | PROT_READ, MAP_SHARED, + phys_ram_fd, phys_ram_size); + if (ptr == MAP_FAILED) { + fprintf(stderr, "Could not map physical memory\n"); + exit(1); + } + phys_ram_size += size; + return ptr; +} + +void qemu_vfree(void *ptr) +{ + /* may be useful some day, but currently we do not need to free */ +} + +#else + +/* alloc shared memory pages */ +void *qemu_vmalloc(size_t size) +{ +#ifdef _BSD + return valloc(size); +#else + return memalign(4096, size); +#endif +} + +void qemu_vfree(void *ptr) +{ + free(ptr); +} + +#endif + #endif void *qemu_mallocz(size_t size)