X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=osdep.c;h=91fb39efaaf4ee7fe614bd3785d380ca3da37173;hb=f3e3aa8cdd139923267a34a474abea4ace60b32f;hp=d1eff8deb5cb0c2a529971c8a4b052d425c88554;hpb=605686cd7acdc37b87134c7eedf01b99db9213c1;p=qemu diff --git a/osdep.c b/osdep.c index d1eff8d..91fb39e 100644 --- a/osdep.c +++ b/osdep.c @@ -1,8 +1,8 @@ /* * QEMU low level functions - * + * * Copyright (c) 2003 Fabrice Bellard - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -27,41 +27,33 @@ #include #include #include +#include #ifdef HOST_SOLARIS #include #include #endif -#include "cpu.h" -#if defined(USE_KQEMU) -#include "vl.h" -#endif +/* Needed early for HOST_BSD etc. */ +#include "config-host.h" #ifdef _WIN32 #include -#elif defined(_BSD) +#elif defined(HOST_BSD) #include #else #include #endif -void *get_mmap_addr(unsigned long size) -{ - return NULL; -} +#include "qemu-common.h" +#include "sysemu.h" +#include "qemu_socket.h" -void qemu_free(void *ptr) -{ - free(ptr); -} - -void *qemu_malloc(size_t size) +#if defined(_WIN32) +void *qemu_memalign(size_t alignment, size_t size) { - return malloc(size); + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); } -#if defined(_WIN32) - void *qemu_vmalloc(size_t size) { /* FIXME: this is not exactly optimal solution since VirtualAlloc @@ -79,17 +71,32 @@ void qemu_vfree(void *ptr) #if defined(USE_KQEMU) +#ifdef __OpenBSD__ +#include +#include +#include +#else +#ifndef __FreeBSD__ #include +#endif +#endif + #include #include -void *kqemu_vmalloc(size_t size) +static void *kqemu_vmalloc(size_t size) { static int phys_ram_fd = -1; static int phys_ram_size = 0; + void *ptr; + +/* no need (?) for a dummy file on OpenBSD/FreeBSD */ +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) + int map_anon = MAP_ANON; +#else + int map_anon = 0; const char *tmpdir; char phys_ram_file[1024]; - void *ptr; #ifdef HOST_SOLARIS struct statvfs stfs; #else @@ -109,20 +116,18 @@ void *kqemu_vmalloc(size_t size) 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, + 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", + "mount -o remount,size=%dm /dev/shm\n", ram_mb + 16); } else { - fprintf(stderr, + 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"); @@ -131,20 +136,20 @@ void *kqemu_vmalloc(size_t size) exit(1); } } - snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", + snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", tmpdir); phys_ram_fd = mkstemp(phys_ram_file); if (phys_ram_fd < 0) { - fprintf(stderr, + 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", + snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", "/tmp"); phys_ram_fd = mkstemp(phys_ram_file); if (phys_ram_fd < 0) { - fprintf(stderr, "Could not create temporary memory file '%s'\n", + fprintf(stderr, "Could not create temporary memory file '%s'\n", phys_ram_file); exit(1); } @@ -153,9 +158,10 @@ void *kqemu_vmalloc(size_t size) } size = (size + 4095) & ~4095; ftruncate(phys_ram_fd, phys_ram_size + size); - ptr = mmap(NULL, - size, - PROT_WRITE | PROT_READ, MAP_SHARED, +#endif /* !(__OpenBSD__ || __FreeBSD__ || __DragonFly__) */ + ptr = mmap(NULL, + size, + PROT_WRITE | PROT_READ, map_anon | MAP_SHARED, phys_ram_fd, phys_ram_size); if (ptr == MAP_FAILED) { fprintf(stderr, "Could not map physical memory\n"); @@ -165,13 +171,29 @@ void *kqemu_vmalloc(size_t size) return ptr; } -void kqemu_vfree(void *ptr) +static void kqemu_vfree(void *ptr) { /* may be useful some day, but currently we do not need to free */ } #endif +void *qemu_memalign(size_t alignment, size_t size) +{ +#if defined(_POSIX_C_SOURCE) + int ret; + void *ptr; + ret = posix_memalign(&ptr, alignment, size); + if (ret != 0) + return NULL; + return ptr; +#elif defined(HOST_BSD) + return valloc(size); +#else + return memalign(alignment, size); +#endif +} + /* alloc shared memory pages */ void *qemu_vmalloc(size_t size) { @@ -179,11 +201,7 @@ void *qemu_vmalloc(size_t size) if (kqemu_allowed) return kqemu_vmalloc(size); #endif -#ifdef _BSD - return valloc(size); -#else - return memalign(4096, size); -#endif + return qemu_memalign(getpagesize(), size); } void qemu_vfree(void *ptr) @@ -197,22 +215,98 @@ void qemu_vfree(void *ptr) #endif -void *qemu_mallocz(size_t size) +int qemu_create_pidfile(const char *filename) { - void *ptr; - ptr = qemu_malloc(size); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; + char buffer[128]; + int len; +#ifndef _WIN32 + int fd; + + fd = open(filename, O_RDWR | O_CREAT, 0600); + if (fd == -1) + return -1; + + if (lockf(fd, F_TLOCK, 0) == -1) + return -1; + + len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); + if (write(fd, buffer, len) != len) + return -1; +#else + HANDLE file; + DWORD flags; + OVERLAPPED overlap; + BOOL ret; + + /* Open for writing with no sharing. */ + file = CreateFile(filename, GENERIC_WRITE, 0, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (file == INVALID_HANDLE_VALUE) + return -1; + + flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; + overlap.hEvent = 0; + /* Lock 1 byte. */ + ret = LockFileEx(file, flags, 0, 0, 1, &overlap); + if (ret == 0) + return -1; + + /* Write PID to file. */ + len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); + ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, + &overlap, NULL); + if (ret == 0) + return -1; +#endif + return 0; } -char *qemu_strdup(const char *str) +#ifdef _WIN32 + +/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000ULL) + +int qemu_gettimeofday(qemu_timeval *tp) { - char *ptr; - ptr = qemu_malloc(strlen(str) + 1); - if (!ptr) - return NULL; - strcpy(ptr, str); - return ptr; + union { + unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + + if(tp) + { + GetSystemTimeAsFileTime (&_now.ft); + tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); + tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); + } + /* Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} +#endif /* _WIN32 */ + + +#ifdef _WIN32 +void socket_set_nonblock(int fd) +{ + unsigned long opt = 1; + ioctlsocket(fd, FIONBIO, &opt); +} + +int inet_aton(const char *cp, struct in_addr *ia) +{ + uint32_t addr = inet_addr(cp); + if (addr == 0xffffffff) + return 0; + ia->s_addr = addr; + return 1; } +#else +void socket_set_nonblock(int fd) +{ + int f; + f = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, f | O_NONBLOCK); +} +#endif