X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=osdep.c;h=f2a69d9a7172c0e56c8598c8a37be119ef662a37;hb=7ef4da1c3a753888e2678388150f1b846b025168;hp=f843e562f1ab055bd7452e3e02cc8725e022ad58;hpb=07d898662d9aa173ac2d5c0aa4c9a1cf39caa703;p=qemu diff --git a/osdep.c b/osdep.c index f843e56..f2a69d9 100644 --- a/osdep.c +++ b/osdep.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include @@ -34,6 +32,9 @@ #if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY) +#include +#include + /* When not using soft mmu, libc independant functions are needed for the CPU core because it needs to use alternates stacks and libc/thread incompatibles settings */ @@ -143,6 +144,22 @@ void *shmat(int shmid, const void *shmaddr, int shmflg) } /****************************************************************/ +/* sigaction bypassing the threads */ + +static int kernel_sigaction(int signum, const struct qemu_sigaction *act, + struct qemu_sigaction *oldact, + int sigsetsize) +{ + QEMU_SYSCALL4(rt_sigaction, signum, act, oldact, sigsetsize); +} + +int qemu_sigaction(int signum, const struct qemu_sigaction *act, + struct qemu_sigaction *oldact) +{ + return kernel_sigaction(signum, act, oldact, 8); +} + +/****************************************************************/ /* memory allocation */ //#define DEBUG_MALLOC @@ -234,6 +251,8 @@ void qemu_free(void *ptr) { MemoryBlock *mb; + if (!ptr) + return; mb = (MemoryBlock *)((uint8_t *)ptr - BLOCK_HEADER_SIZE); mb->next = first_free_block; first_free_block = mb; @@ -254,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; @@ -279,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) @@ -291,6 +439,16 @@ void *qemu_mallocz(size_t size) return ptr; } +char *qemu_strdup(const char *str) +{ + char *ptr; + ptr = qemu_malloc(strlen(str) + 1); + if (!ptr) + return NULL; + strcpy(ptr, str); + return ptr; +} + /****************************************************************/ /* printf support */