mirror of https://github.com/xqemu/xqemu.git
wxx patch queue
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWBE4CAAoJEOCMIdVndFCtv+YP/ieFC5jYs4OHW3y9KCFk1PIJ 7NNQrURf6bIZzbJWrMyloa0Tcv5tSgi6tfha6K2nUGTw+dyUKEfUM7WugadEKc8U 7oLmExJ+QTog7wTdLzZecfaZ2z8cpHihUTn4YQlmAgUy52b1FEo6DW0lDvte7bU0 LY3o9IPL9pFkH6BDyXqfwbQK55slHmR+iCB9IJUI13sRdpA0wRiKH+w0Kd0yR2SY Krqz8dC1DC+TKu04rpFIszy9HAxUMxO/JVVrfz7Tft/Mmi5vxrfyuPABocsPjsXf Xv55YYwu03J0v01f4AaVpap6MaypXotm0eyktWY0kqqhePoSU5+2qqwjZaVzsUYU ddTMHukDCoNHhFQmOGnMZ49nPvrx1UoIsy84El6Q3tyF6dUSSy0XfXLoB8lWN7j4 ZZa+jSC4FChuejxxcspjnlogg/bguW8uAQttB7ASiDr46PIpCWZTYLiDs1KO2b4J BKmlKXHVkdG026rZOekeGzkObnfOMOKUqig9nDBbfB1ULBk2TQuI5i0GSYj3Crlm v9okF420xHKRBTa1gbP9Rl2122bHwtYwVnIwzACtbK6kJ6cnZv2u2j1MwGQOd4i4 5D40HhmXElNYfcluFMVmGlfvNv6W4oVe/id9bP4s9x4mmtXJl0+/ZVjoS2mqo0AT 4ZQdR3DRLXe3F4LHPJQP =xdVb -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/weil/tags/pull-wxx-20150924' into staging wxx patch queue # gpg: Signature made Thu 24 Sep 2015 20:24:50 BST using RSA key ID 677450AD # gpg: Good signature from "Stefan Weil <sw@weilnetz.de>" # gpg: aka "Stefan Weil <stefan.weil@weilnetz.de>" # gpg: aka "Stefan Weil <stefan.weil@bib.uni-mannheim.de>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 4923 6FEA 75C9 5D69 8EC2 B78A E08C 21D5 6774 50AD * remotes/weil/tags/pull-wxx-20150924: oslib-win32: only provide localtime_r/gmtime_r if missing gtk: avoid redefining _WIN32_WINNT macro qemu-thread: add a fast path to the Win32 QemuEvent slirp: Fix non blocking connect for w32 nsis: Add QEMU version information to Windows registry Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8a47d575df
1
Makefile
1
Makefile
|
@ -623,6 +623,7 @@ endif # SIGNCODE
|
|||
$(if $(DLL_PATH),-DDLLDIR="$(DLL_PATH)") \
|
||||
-DSRCDIR="$(SRC_PATH)" \
|
||||
-DOUTFILE="$(INSTALLER)" \
|
||||
-DDISPLAYVERSION="$(VERSION)" \
|
||||
$(SRC_PATH)/qemu.nsi
|
||||
rm -r ${INSTDIR}
|
||||
ifdef SIGNCODE
|
||||
|
|
|
@ -1736,6 +1736,37 @@ else
|
|||
l2tpv3=no
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# MinGW / Mingw-w64 localtime_r/gmtime_r check
|
||||
|
||||
if test "$mingw32" = "yes"; then
|
||||
# Some versions of MinGW / Mingw-w64 lack localtime_r
|
||||
# and gmtime_r entirely.
|
||||
#
|
||||
# Some versions of Mingw-w64 define a macro for
|
||||
# localtime_r/gmtime_r.
|
||||
#
|
||||
# Some versions of Mingw-w64 will define functions
|
||||
# for localtime_r/gmtime_r, but only if you have
|
||||
# _POSIX_THREAD_SAFE_FUNCTIONS defined. For fun
|
||||
# though, unistd.h and pthread.h both define
|
||||
# that for you.
|
||||
#
|
||||
# So this #undef localtime_r and #include <unistd.h>
|
||||
# are not in fact redundant.
|
||||
cat > $TMPC << EOF
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#undef localtime_r
|
||||
int main(void) { localtime_r(NULL, NULL); return 0; }
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
localtime_r="yes"
|
||||
else
|
||||
localtime_r="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# pkg-config probe
|
||||
|
||||
|
@ -5034,6 +5065,9 @@ fi
|
|||
if test "$zero_malloc" = "yes" ; then
|
||||
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$localtime_r" = "yes" ; then
|
||||
echo "CONFIG_LOCALTIME_R=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$qom_cast_debug" = "yes" ; then
|
||||
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* This model describes the implementation of QemuEvent in
|
||||
* util/qemu-thread-win32.c.
|
||||
*
|
||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
*
|
||||
* This file is in the public domain. If you really want a license,
|
||||
* the WTFPL will do.
|
||||
*
|
||||
* To verify it:
|
||||
* spin -a docs/event.promela
|
||||
* gcc -O2 pan.c -DSAFETY
|
||||
* ./a.out
|
||||
*/
|
||||
|
||||
bool event;
|
||||
int value;
|
||||
|
||||
/* Primitives for a Win32 event */
|
||||
#define RAW_RESET event = false
|
||||
#define RAW_SET event = true
|
||||
#define RAW_WAIT do :: event -> break; od
|
||||
|
||||
#if 0
|
||||
/* Basic sanity checking: test the Win32 event primitives */
|
||||
#define RESET RAW_RESET
|
||||
#define SET RAW_SET
|
||||
#define WAIT RAW_WAIT
|
||||
#else
|
||||
/* Full model: layer a userspace-only fast path on top of the RAW_*
|
||||
* primitives. SET/RESET/WAIT have exactly the same semantics as
|
||||
* RAW_SET/RAW_RESET/RAW_WAIT, but try to avoid invoking them.
|
||||
*/
|
||||
#define EV_SET 0
|
||||
#define EV_FREE 1
|
||||
#define EV_BUSY -1
|
||||
|
||||
int state = EV_FREE;
|
||||
|
||||
int xchg_result;
|
||||
#define SET if :: state != EV_SET -> \
|
||||
atomic { /* xchg_result=xchg(state, EV_SET) */ \
|
||||
xchg_result = state; \
|
||||
state = EV_SET; \
|
||||
} \
|
||||
if :: xchg_result == EV_BUSY -> RAW_SET; \
|
||||
:: else -> skip; \
|
||||
fi; \
|
||||
:: else -> skip; \
|
||||
fi
|
||||
|
||||
#define RESET if :: state == EV_SET -> atomic { state = state | EV_FREE; } \
|
||||
:: else -> skip; \
|
||||
fi
|
||||
|
||||
int tmp1, tmp2;
|
||||
#define WAIT tmp1 = state; \
|
||||
if :: tmp1 != EV_SET -> \
|
||||
if :: tmp1 == EV_FREE -> \
|
||||
RAW_RESET; \
|
||||
atomic { /* tmp2=cas(state, EV_FREE, EV_BUSY) */ \
|
||||
tmp2 = state; \
|
||||
if :: tmp2 == EV_FREE -> state = EV_BUSY; \
|
||||
:: else -> skip; \
|
||||
fi; \
|
||||
} \
|
||||
if :: tmp2 == EV_SET -> tmp1 = EV_SET; \
|
||||
:: else -> tmp1 = EV_BUSY; \
|
||||
fi; \
|
||||
:: else -> skip; \
|
||||
fi; \
|
||||
assert(tmp1 != EV_FREE); \
|
||||
if :: tmp1 == EV_BUSY -> RAW_WAIT; \
|
||||
:: else -> skip; \
|
||||
fi; \
|
||||
:: else -> skip; \
|
||||
fi
|
||||
#endif
|
||||
|
||||
active proctype waiter()
|
||||
{
|
||||
if
|
||||
:: !value ->
|
||||
RESET;
|
||||
if
|
||||
:: !value -> WAIT;
|
||||
:: else -> skip;
|
||||
fi;
|
||||
:: else -> skip;
|
||||
fi;
|
||||
assert(value);
|
||||
}
|
||||
|
||||
active proctype notifier()
|
||||
{
|
||||
value = true;
|
||||
SET;
|
||||
}
|
|
@ -38,10 +38,12 @@
|
|||
#include <strings.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
/* Put unistd.h before time.h as that triggers localtime_r/gmtime_r
|
||||
* function availability on recentish Mingw-w64 platforms. */
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
|
|
@ -18,6 +18,7 @@ struct QemuSemaphore {
|
|||
};
|
||||
|
||||
struct QemuEvent {
|
||||
int value;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,10 +73,12 @@
|
|||
#define siglongjmp(env, val) longjmp(env, val)
|
||||
|
||||
/* Missing POSIX functions. Don't use MinGW-w64 macros. */
|
||||
#ifndef CONFIG_LOCALTIME_R
|
||||
#undef gmtime_r
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#undef localtime_r
|
||||
struct tm *localtime_r(const time_t *timep, struct tm *result);
|
||||
#endif /* CONFIG_LOCALTIME_R */
|
||||
|
||||
|
||||
static inline void os_setup_signal_handling(void) {}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#ifndef UI_GTK_H
|
||||
#define UI_GTK_H
|
||||
|
||||
#ifdef _WIN32
|
||||
# define _WIN32_WINNT 0x0601 /* needed to get definition of MAPVK_VK_TO_VSC */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||
/* Work around an -Wstrict-prototypes warning in GTK headers */
|
||||
#pragma GCC diagnostic push
|
||||
|
|
3
qemu.nsi
3
qemu.nsi
|
@ -139,6 +139,9 @@ Section "${PRODUCT} (required)"
|
|||
|
||||
; Write the uninstall keys for Windows
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "QEMU"
|
||||
!ifdef DISPLAYVERSION
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${DISPLAYVERSION}"
|
||||
!endif
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"${UNINST_EXE}"'
|
||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 1
|
||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 1
|
||||
|
|
|
@ -584,7 +584,13 @@ findso:
|
|||
goto cont_input;
|
||||
}
|
||||
|
||||
if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
|
||||
if ((tcp_fconnect(so) == -1) &&
|
||||
#if defined(_WIN32)
|
||||
socket_error() != WSAEWOULDBLOCK
|
||||
#else
|
||||
(errno != EINPROGRESS) && (errno != EWOULDBLOCK)
|
||||
#endif
|
||||
) {
|
||||
u_char code=ICMP_UNREACH_NET;
|
||||
DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n",
|
||||
errno,strerror(errno)));
|
||||
|
|
9
ui/gtk.c
9
ui/gtk.c
|
@ -104,6 +104,15 @@
|
|||
#define GDK_KEY_Pause GDK_Pause
|
||||
#endif
|
||||
|
||||
/* Some older mingw versions lack this constant or have
|
||||
* it conditionally defined */
|
||||
#ifdef _WIN32
|
||||
# ifndef MAPVK_VK_TO_VSC
|
||||
# define MAPVK_VK_TO_VSC 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
|
||||
|
||||
static const int modifier_keycode[] = {
|
||||
|
|
|
@ -95,6 +95,7 @@ void qemu_anon_ram_free(void *ptr, size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LOCALTIME_R
|
||||
/* FIXME: add proper locking */
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result)
|
||||
{
|
||||
|
@ -118,6 +119,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
|
|||
}
|
||||
return p;
|
||||
}
|
||||
#endif /* CONFIG_LOCALTIME_R */
|
||||
|
||||
void qemu_set_block(int fd)
|
||||
{
|
||||
|
|
|
@ -238,10 +238,34 @@ void qemu_sem_wait(QemuSemaphore *sem)
|
|||
}
|
||||
}
|
||||
|
||||
/* Wrap a Win32 manual-reset event with a fast userspace path. The idea
|
||||
* is to reset the Win32 event lazily, as part of a test-reset-test-wait
|
||||
* sequence. Such a sequence is, indeed, how QemuEvents are used by
|
||||
* RCU and other subsystems!
|
||||
*
|
||||
* Valid transitions:
|
||||
* - free->set, when setting the event
|
||||
* - busy->set, when setting the event, followed by futex_wake
|
||||
* - set->free, when resetting the event
|
||||
* - free->busy, when waiting
|
||||
*
|
||||
* set->busy does not happen (it can be observed from the outside but
|
||||
* it really is set->free->busy).
|
||||
*
|
||||
* busy->free provably cannot happen; to enforce it, the set->free transition
|
||||
* is done with an OR, which becomes a no-op if the event has concurrently
|
||||
* transitioned to free or busy (and is faster than cmpxchg).
|
||||
*/
|
||||
|
||||
#define EV_SET 0
|
||||
#define EV_FREE 1
|
||||
#define EV_BUSY -1
|
||||
|
||||
void qemu_event_init(QemuEvent *ev, bool init)
|
||||
{
|
||||
/* Manual reset. */
|
||||
ev->event = CreateEvent(NULL, TRUE, init, NULL);
|
||||
ev->event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
ev->value = (init ? EV_SET : EV_FREE);
|
||||
}
|
||||
|
||||
void qemu_event_destroy(QemuEvent *ev)
|
||||
|
@ -251,17 +275,51 @@ void qemu_event_destroy(QemuEvent *ev)
|
|||
|
||||
void qemu_event_set(QemuEvent *ev)
|
||||
{
|
||||
SetEvent(ev->event);
|
||||
if (atomic_mb_read(&ev->value) != EV_SET) {
|
||||
if (atomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
|
||||
/* There were waiters, wake them up. */
|
||||
SetEvent(ev->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_event_reset(QemuEvent *ev)
|
||||
{
|
||||
ResetEvent(ev->event);
|
||||
if (atomic_mb_read(&ev->value) == EV_SET) {
|
||||
/* If there was a concurrent reset (or even reset+wait),
|
||||
* do nothing. Otherwise change EV_SET->EV_FREE.
|
||||
*/
|
||||
atomic_or(&ev->value, EV_FREE);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_event_wait(QemuEvent *ev)
|
||||
{
|
||||
WaitForSingleObject(ev->event, INFINITE);
|
||||
unsigned value;
|
||||
|
||||
value = atomic_mb_read(&ev->value);
|
||||
if (value != EV_SET) {
|
||||
if (value == EV_FREE) {
|
||||
/* qemu_event_set is not yet going to call SetEvent, but we are
|
||||
* going to do another check for EV_SET below when setting EV_BUSY.
|
||||
* At that point it is safe to call WaitForSingleObject.
|
||||
*/
|
||||
ResetEvent(ev->event);
|
||||
|
||||
/* Tell qemu_event_set that there are waiters. No need to retry
|
||||
* because there cannot be a concurent busy->free transition.
|
||||
* After the CAS, the event will be either set or busy.
|
||||
*/
|
||||
if (atomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
|
||||
value = EV_SET;
|
||||
} else {
|
||||
value = EV_BUSY;
|
||||
}
|
||||
}
|
||||
if (value == EV_BUSY) {
|
||||
WaitForSingleObject(ev->event, INFINITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct QemuThreadData {
|
||||
|
|
Loading…
Reference in New Issue