1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <stdlib.h>
25: #include <stdio.h>
26: #include <stdarg.h>
27: #include <string.h>
28: #include <errno.h>
29: #include <unistd.h>
30: #include <fcntl.h>
31: #ifdef HOST_SOLARIS
32: #include <sys/types.h>
33: #include <sys/statvfs.h>
34: #endif
35:
36: #include "qemu-common.h"
37: #include "sysemu.h"
38:
39: #ifdef _WIN32
40: #define WIN32_LEAN_AND_MEAN
41: #include <windows.h>
42: #elif defined(_BSD)
43: #include <stdlib.h>
44: #else
45: #include <malloc.h>
46: #endif
47:
48: void *get_mmap_addr(unsigned long size)
49: {
50: return NULL;
51: }
52:
53: void qemu_free(void *ptr)
54: {
55: free(ptr);
56: }
57:
58: void *qemu_malloc(size_t size)
59: {
60: return malloc(size);
61: }
62:
63: #if defined(_WIN32)
64: void *qemu_memalign(size_t alignment, size_t size)
65: {
66: return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
67: }
68:
69: void *qemu_vmalloc(size_t size)
70: {
71:
72:
73:
74: return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
75: }
76:
77: void qemu_vfree(void *ptr)
78: {
79: VirtualFree(ptr, 0, MEM_RELEASE);
80: }
81:
82: #else
83:
84: #if defined(USE_KQEMU)
85:
86: #include <sys/vfs.h>
87: #include <sys/mman.h>
88: #include <fcntl.h>
89:
90: static void *kqemu_vmalloc(size_t size)
91: {
92: static int phys_ram_fd = -1;
93: static int phys_ram_size = 0;
94: const char *tmpdir;
95: char phys_ram_file[1024];
96: void *ptr;
97: #ifdef HOST_SOLARIS
98: struct statvfs stfs;
99: #else
100: struct statfs stfs;
101: #endif
102:
103: if (phys_ram_fd < 0) {
104: tmpdir = getenv("QEMU_TMPDIR");
105: if (!tmpdir)
106: #ifdef HOST_SOLARIS
107: tmpdir = "/tmp";
108: if (statvfs(tmpdir, &stfs) == 0) {
109: #else
110: tmpdir = "/dev/shm";
111: if (statfs(tmpdir, &stfs) == 0) {
112: #endif
113: int64_t free_space;
114: int ram_mb;
115:
116: extern int ram_size;
117: free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
118: if ((ram_size + 8192 * 1024) >= free_space) {
119: ram_mb = (ram_size / (1024 * 1024));
120: fprintf(stderr,
121: "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
122: tmpdir, ram_mb);
123: if (strcmp(tmpdir, "/dev/shm") == 0) {
124: fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
125: "umount /dev/shm\n"
126: "mount -t tmpfs -o size=%dm none /dev/shm\n",
127: ram_mb + 16);
128: } else {
129: fprintf(stderr,
130: "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
131: "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
132: "temporary RAM file will be opened.\n");
133: }
134: fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
135: exit(1);
136: }
137: }
138: snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
139: tmpdir);
140: phys_ram_fd = mkstemp(phys_ram_file);
141: if (phys_ram_fd < 0) {
142: fprintf(stderr,
143: "warning: could not create temporary file in '%s'.\n"
144: "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
145: "Using '/tmp' as fallback.\n",
146: tmpdir);
147: snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
148: "/tmp");
149: phys_ram_fd = mkstemp(phys_ram_file);
150: if (phys_ram_fd < 0) {
151: fprintf(stderr, "Could not create temporary memory file '%s'\n",
152: phys_ram_file);
153: exit(1);
154: }
155: }
156: unlink(phys_ram_file);
157: }
158: size = (size + 4095) & ~4095;
159: ftruncate(phys_ram_fd, phys_ram_size + size);
160: ptr = mmap(NULL,
161: size,
162: PROT_WRITE | PROT_READ, MAP_SHARED,
163: phys_ram_fd, phys_ram_size);
164: if (ptr == MAP_FAILED) {
165: fprintf(stderr, "Could not map physical memory\n");
166: exit(1);
167: }
168: phys_ram_size += size;
169: return ptr;
170: }
171:
172: static void kqemu_vfree(void *ptr)
173: {
174:
175: }
176:
177: #endif
178:
179: void *qemu_memalign(size_t alignment, size_t size)
180: {
181: #if defined(_POSIX_C_SOURCE)
182: int ret;
183: void *ptr;
184: ret = posix_memalign(&ptr, alignment, size);
185: if (ret != 0)
186: return NULL;
187: return ptr;
188: #elif defined(_BSD)
189: return valloc(size);
190: #else
191: return memalign(alignment, size);
192: #endif
193: }
194:
195:
196: void *qemu_vmalloc(size_t size)
197: {
198: #if defined(USE_KQEMU)
199: if (kqemu_allowed)
200: return kqemu_vmalloc(size);
201: #endif
202: #ifdef _BSD
203: return valloc(size);
204: #else
205: return memalign(4096, size);
206: #endif
207: }
208:
209: void qemu_vfree(void *ptr)
210: {
211: #if defined(USE_KQEMU)
212: if (kqemu_allowed)
213: kqemu_vfree(ptr);
214: #endif
215: free(ptr);
216: }
217:
218: #endif
219:
220: void *qemu_mallocz(size_t size)
221: {
222: void *ptr;
223: ptr = qemu_malloc(size);
224: if (!ptr)
225: return NULL;
226: memset(ptr, 0, size);
227: return ptr;
228: }
229:
230: char *qemu_strdup(const char *str)
231: {
232: char *ptr;
233: ptr = qemu_malloc(strlen(str) + 1);
234: if (!ptr)
235: return NULL;
236: strcpy(ptr, str);
237: return ptr;
238: }
239:
240: int qemu_create_pidfile(const char *filename)
241: {
242: char buffer[128];
243: int len;
244: #ifndef _WIN32
245: int fd;
246:
247: fd = open(filename, O_RDWR | O_CREAT, 0600);
248: if (fd == -1)
249: return -1;
250:
251: if (lockf(fd, F_TLOCK, 0) == -1)
252: return -1;
253:
254: len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
255: if (write(fd, buffer, len) != len)
256: return -1;
257: #else
258: HANDLE file;
259: DWORD flags;
260: OVERLAPPED overlap;
261: BOOL ret;
262:
263:
264: file = CreateFile(filename, GENERIC_WRITE, 0, NULL,
265: OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
266:
267: if (file == INVALID_HANDLE_VALUE)
268: return -1;
269:
270: flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
271: overlap.hEvent = 0;
272:
273: ret = LockFileEx(file, flags, 0, 0, 1, &overlap);
274: if (ret == 0)
275: return -1;
276:
277:
278: len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
279: ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
280: &overlap, NULL);
281: if (ret == 0)
282: return -1;
283: #endif
284: return 0;
285: }
286:
287: #ifdef _WIN32
288:
289:
290: #define _W32_FT_OFFSET (116444736000000000ULL)
291:
292: int qemu_gettimeofday(qemu_timeval *tp)
293: {
294: union {
295: unsigned long long ns100;
296: FILETIME ft;
297: } _now;
298:
299: if(tp)
300: {
301: GetSystemTimeAsFileTime (&_now.ft);
302: tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
303: tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
304: }
305:
306:
307: return 0;
308: }
309: #endif