Merge branch 'noglib' of https://github.com/cseagle/unicorn into cseagle-noglib

This commit is contained in:
Nguyen Anh Quynh
2016-12-19 17:32:27 +08:00
79 changed files with 1073 additions and 1358 deletions

View File

@ -67,7 +67,7 @@ void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
msg1 = g_strdup_vprintf(fmt, ap);
if (os_errno != 0) {
err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
g_free(msg1);
free(msg1);
} else {
err->msg = msg1;
}
@ -110,8 +110,8 @@ void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
char *msg2 = g_win32_error_message(win32_err);
err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
(unsigned)win32_err);
g_free(msg2);
g_free(msg1);
free(msg2);
free(msg1);
} else {
err->msg = msg1;
}
@ -152,8 +152,8 @@ const char *error_get_pretty(Error *err)
void error_free(Error *err)
{
if (err) {
g_free(err->msg);
g_free(err);
free(err->msg);
free(err);
}
}

View File

@ -51,8 +51,6 @@ extern int daemon(int, int);
#include <termios.h>
#include <unistd.h>
#include <glib/gprintf.h>
#include "config-host.h"
#include "sysemu/sysemu.h"
#include <sys/mman.h>
@ -183,13 +181,6 @@ int qemu_pipe(int pipefd[2])
return ret;
}
char *
qemu_get_local_state_pathname(const char *relative_pathname)
{
return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
relative_pathname);
}
void qemu_set_tty_echo(int fd, bool echo)
{
struct termios tty;

View File

@ -25,15 +25,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* The implementation of g_poll (functions poll_rest, g_poll) at the end of
* this file are based on code from GNOME glib-2 and use a different license,
* see the license comment there.
*/
#include <windows.h>
#define G_OS_WIN32
#include <glib.h>
#include <stdlib.h>
#include "config-host.h"
#include "sysemu/sysemu.h"
@ -156,23 +150,6 @@ int qemu_gettimeofday(qemu_timeval *tp)
return 0;
}
char *
qemu_get_local_state_pathname(const char *relative_pathname)
{
HRESULT result;
char base_path[MAX_PATH+1] = "";
result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
/* SHGFP_TYPE_CURRENT */ 0, base_path);
if (result != S_OK) {
/* misconfigured environment */
g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
abort();
}
return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
relative_pathname);
}
void qemu_set_tty_echo(int fd, bool echo)
{
HANDLE handle = (HANDLE)_get_osfhandle(fd);
@ -192,210 +169,6 @@ void qemu_set_tty_echo(int fd, bool echo)
}
}
/*
* The original implementation of g_poll from glib has a problem on Windows
* when using timeouts < 10 ms.
*
* Whenever g_poll is called with timeout < 10 ms, it does a quick poll instead
* of wait. This causes significant performance degradation of QEMU.
*
* The following code is a copy of the original code from glib/gpoll.c
* (glib commit 20f4d1820b8d4d0fc4447188e33efffd6d4a88d8 from 2014-02-19).
* Some debug code was removed and the code was reformatted.
* All other code modifications are marked with 'QEMU'.
*/
/*
* gpoll.c: poll(2) abstraction
* Copyright 1998 Owen Taylor
* Copyright 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
GPollFD *fds, guint nfds, gint timeout)
{
DWORD ready;
GPollFD *f;
int recursed_result;
if (poll_msgs) {
/* Wait for either messages or handles
* -> Use MsgWaitForMultipleObjectsEx
*/
ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
QS_ALLINPUT, MWMO_ALERTABLE);
if (ready == WAIT_FAILED) {
gchar *emsg = g_win32_error_message(GetLastError());
g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
g_free(emsg);
}
} else if (nhandles == 0) {
/* No handles to wait for, just the timeout */
if (timeout == INFINITE) {
ready = WAIT_FAILED;
} else {
SleepEx(timeout, TRUE);
ready = WAIT_TIMEOUT;
}
} else {
/* Wait for just handles
* -> Use WaitForMultipleObjectsEx
*/
ready =
WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
if (ready == WAIT_FAILED) {
gchar *emsg = g_win32_error_message(GetLastError());
g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
g_free(emsg);
}
}
if (ready == WAIT_FAILED) {
return -1;
} else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
return 0;
} else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
for (f = fds; f < &fds[nfds]; ++f) {
if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
f->revents |= G_IO_IN;
}
}
/* If we have a timeout, or no handles to poll, be satisfied
* with just noticing we have messages waiting.
*/
if (timeout != 0 || nhandles == 0) {
return 1;
}
/* If no timeout and handles to poll, recurse to poll them,
* too.
*/
recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
return (recursed_result == -1) ? -1 : 1 + recursed_result;
} else if (/* QEMU: removed the following unneeded statement which causes
* a compiler warning: ready >= WAIT_OBJECT_0 && */
ready < WAIT_OBJECT_0 + nhandles) {
for (f = fds; f < &fds[nfds]; ++f) {
if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
f->revents = f->events;
}
}
/* If no timeout and polling several handles, recurse to poll
* the rest of them.
*/
if (timeout == 0 && nhandles > 1) {
/* Remove the handle that fired */
int i;
if (ready < nhandles - 1) {
for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
handles[i-1] = handles[i];
}
}
nhandles--;
recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
return (recursed_result == -1) ? -1 : 1 + recursed_result;
}
return 1;
}
return 0;
}
gint g_poll(GPollFD *fds, guint nfds, gint timeout)
{
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
gboolean poll_msgs = FALSE;
GPollFD *f;
gint nhandles = 0;
int retval;
for (f = fds; f < &fds[nfds]; ++f) {
if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
poll_msgs = TRUE;
} else if (f->fd > 0) {
/* Don't add the same handle several times into the array, as
* docs say that is not allowed, even if it actually does seem
* to work.
*/
gint i;
for (i = 0; i < nhandles; i++) {
if (handles[i] == (HANDLE) f->fd) {
break;
}
}
if (i == nhandles) {
if (nhandles == MAXIMUM_WAIT_OBJECTS) {
g_warning("Too many handles to wait for!\n");
break;
} else {
handles[nhandles++] = (HANDLE) f->fd;
}
}
}
}
for (f = fds; f < &fds[nfds]; ++f) {
f->revents = 0;
}
if (timeout == -1) {
timeout = INFINITE;
}
/* Polling for several things? */
if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
/* First check if one or several of them are immediately
* available
*/
retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);
/* If not, and we have a significant timeout, poll again with
* timeout then. Note that this will return indication for only
* one event, or only for messages. We ignore timeouts less than
* ten milliseconds as they are mostly pointless on Windows, the
* MsgWaitForMultipleObjectsEx() call will timeout right away
* anyway.
*
* Modification for QEMU: replaced timeout >= 10 by timeout > 0.
*/
if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
retval = poll_rest(poll_msgs, handles, nhandles,
fds, nfds, timeout);
}
} else {
/* Just polling for one thing, so no need to check first if
* available immediately
*/
retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
}
if (retval == -1) {
for (f = fds; f < &fds[nfds]; ++f) {
f->revents = 0;
}
}
return retval;
}
size_t getpagesize(void)
{
SYSTEM_INFO system_info;

View File

@ -288,9 +288,9 @@ QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
static void qemu_opt_del(QemuOpt *opt)
{
QTAILQ_REMOVE(&opt->opts->head, opt, next);
g_free(opt->name);
g_free(opt->str);
g_free(opt);
free(opt->name);
free(opt->str);
free(opt);
}
/* qemu_opt_set allows many settings for the same option.
@ -327,7 +327,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
/* Get a known option (or its default) and remove it from the list
* all in one action. Return a malloced string of the option value.
* Result must be freed by caller with g_free().
* Result must be freed by caller with free().
*/
char *qemu_opt_get_del(QemuOpts *opts, const char *name)
{
@ -576,7 +576,7 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
opt->desc = find_desc_by_name(desc, name);
if (!opt->desc && !opts_accepts_any(opts)) {
qerror_report(QERR_INVALID_PARAMETER, name);
g_free(opt);
free(opt);
return -1;
}
@ -598,7 +598,7 @@ int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
opt->desc = find_desc_by_name(desc, name);
if (!opt->desc && !opts_accepts_any(opts)) {
qerror_report(QERR_INVALID_PARAMETER, name);
g_free(opt);
free(opt);
return -1;
}
@ -698,7 +698,7 @@ const char *qemu_opts_id(QemuOpts *opts)
return opts->id;
}
/* The id string will be g_free()d by qemu_opts_del */
/* The id string will be free()d by qemu_opts_del */
void qemu_opts_set_id(QemuOpts *opts, char *id)
{
opts->id = id;
@ -719,8 +719,8 @@ void qemu_opts_del(QemuOpts *opts)
qemu_opt_del(opt);
}
QTAILQ_REMOVE(&opts->list->head, opts, next);
g_free(opts->id);
g_free(opts);
free(opts->id);
free(opts);
}
void qemu_opts_print(QemuOpts *opts)
@ -1064,7 +1064,7 @@ static size_t count_opts_list(QemuOptsList *list)
void qemu_opts_free(QemuOptsList *list)
{
g_free(list);
free(list);
}
/* Realloc dst option list and append options from an option list (list)

View File

@ -277,7 +277,7 @@ static unsigned __stdcall win32_start_routine(void *arg)
if (data->mode == QEMU_THREAD_DETACHED) {
data->uc->qemu_thread_data = NULL;
g_free(data);
free(data);
data = NULL;
}
qemu_thread_exit(data->uc, start_routine(thread_arg));
@ -323,7 +323,7 @@ void *qemu_thread_join(QemuThread *thread)
ret = data->ret;
assert(data->mode != QEMU_THREAD_DETACHED);
DeleteCriticalSection(&data->cs);
g_free(data);
free(data);
return ret;
}