diff options
Diffstat (limited to 'include/qemu')
| -rw-r--r-- | include/qemu/config-file.h | 4 | ||||
| -rw-r--r-- | include/qemu/coroutine.h | 6 | ||||
| -rw-r--r-- | include/qemu/event_notifier.h | 3 | ||||
| -rw-r--r-- | include/qemu/futex.h | 36 | ||||
| -rw-r--r-- | include/qemu/host-utils.h | 25 | ||||
| -rw-r--r-- | include/qemu/main-loop.h | 15 | ||||
| -rw-r--r-- | include/qemu/qht.h | 2 | ||||
| -rw-r--r-- | include/qemu/queue.h | 60 | ||||
| -rw-r--r-- | include/qemu/sockets.h | 2 | ||||
| -rw-r--r-- | include/qemu/thread.h | 112 | ||||
| -rw-r--r-- | include/qemu/xattr.h | 2 |
11 files changed, 244 insertions, 23 deletions
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h index 8d4b2b6d94..c80d5c8a33 100644 --- a/include/qemu/config-file.h +++ b/include/qemu/config-file.h @@ -23,8 +23,4 @@ int qemu_read_config_file(const char *filename); void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists, Error **errp); -/* Read default QEMU config files - */ -int qemu_read_default_config_files(bool userconfig); - #endif /* QEMU_CONFIG_FILE_H */ diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index e6a60d55fd..12584ed1b7 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -71,6 +71,12 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque); void qemu_coroutine_enter(Coroutine *coroutine); /** + * Transfer control to a coroutine if it's not active (i.e. part of the call + * stack of the running coroutine). Otherwise, do nothing. + */ +void qemu_coroutine_enter_if_inactive(Coroutine *co); + +/** * Transfer control back to a coroutine's caller * * This function does not return until the coroutine is re-entered using diff --git a/include/qemu/event_notifier.h b/include/qemu/event_notifier.h index e326990db4..599c99f1a5 100644 --- a/include/qemu/event_notifier.h +++ b/include/qemu/event_notifier.h @@ -34,9 +34,6 @@ int event_notifier_init(EventNotifier *, int active); void event_notifier_cleanup(EventNotifier *); int event_notifier_set(EventNotifier *); int event_notifier_test_and_clear(EventNotifier *); -int event_notifier_set_handler(EventNotifier *, - bool is_external, - EventNotifierHandler *); #ifdef CONFIG_POSIX void event_notifier_init_fd(EventNotifier *, int fd); diff --git a/include/qemu/futex.h b/include/qemu/futex.h new file mode 100644 index 0000000000..bb7dc9e296 --- /dev/null +++ b/include/qemu/futex.h @@ -0,0 +1,36 @@ +/* + * Wrappers around Linux futex syscall + * + * Copyright Red Hat, Inc. 2017 + * + * Author: + * Paolo Bonzini <pbonzini@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include <sys/syscall.h> +#include <linux/futex.h> + +#define qemu_futex(...) syscall(__NR_futex, __VA_ARGS__) + +static inline void qemu_futex_wake(void *f, int n) +{ + qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0); +} + +static inline void qemu_futex_wait(void *f, unsigned val) +{ + while (qemu_futex(f, FUTEX_WAIT, (int) val, NULL, NULL, 0)) { + switch (errno) { + case EWOULDBLOCK: + return; + case EINTR: + break; /* get out of switch and retry */ + default: + abort(); + } + } +} diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h index 46187bbc7e..96288d0bce 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -327,7 +327,7 @@ static inline int ctpop8(uint8_t val) #else val = (val & 0x55) + ((val >> 1) & 0x55); val = (val & 0x33) + ((val >> 2) & 0x33); - val = (val & 0x0f) + ((val >> 4) & 0x0f); + val = (val + (val >> 4)) & 0x0f; return val; #endif @@ -344,8 +344,8 @@ static inline int ctpop16(uint16_t val) #else val = (val & 0x5555) + ((val >> 1) & 0x5555); val = (val & 0x3333) + ((val >> 2) & 0x3333); - val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f); - val = (val & 0x00ff) + ((val >> 8) & 0x00ff); + val = (val + (val >> 4)) & 0x0f0f; + val = (val + (val >> 8)) & 0x00ff; return val; #endif @@ -360,11 +360,10 @@ static inline int ctpop32(uint32_t val) #if QEMU_GNUC_PREREQ(3, 4) return __builtin_popcount(val); #else - val = (val & 0x55555555) + ((val >> 1) & 0x55555555); - val = (val & 0x33333333) + ((val >> 2) & 0x33333333); - val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); - val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff); - val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); + val = (val & 0x55555555) + ((val >> 1) & 0x55555555); + val = (val & 0x33333333) + ((val >> 2) & 0x33333333); + val = (val + (val >> 4)) & 0x0f0f0f0f; + val = (val * 0x01010101) >> 24; return val; #endif @@ -379,12 +378,10 @@ static inline int ctpop64(uint64_t val) #if QEMU_GNUC_PREREQ(3, 4) return __builtin_popcountll(val); #else - val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); - val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); - val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); - val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL); - val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL); - val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); + val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); + val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); + val = (val + (val >> 4)) & 0x0f0f0f0f0f0f0f0fULL; + val = (val * 0x0101010101010101ULL) >> 56; return val; #endif diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index a9d4f23cd9..d7e24af78d 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -203,6 +203,21 @@ void qemu_set_fd_handler(int fd, IOHandler *fd_write, void *opaque); + +/** + * event_notifier_set_handler: Register an EventNotifier with the main loop + * + * This function tells the main loop to wake up whenever the + * #EventNotifier was set. + * + * @e: The #EventNotifier to be observed. + * + * @handler: A level-triggered callback that is fired when @e + * has been set. @e is passed to it as a parameter. + */ +void event_notifier_set_handler(EventNotifier *e, + EventNotifierHandler *handler); + GSource *iohandler_get_g_source(void); AioContext *iohandler_get_aio_context(void); #ifdef CONFIG_POSIX diff --git a/include/qemu/qht.h b/include/qemu/qht.h index 311139b85a..56c2c7784c 100644 --- a/include/qemu/qht.h +++ b/include/qemu/qht.h @@ -72,7 +72,7 @@ void qht_destroy(struct qht *ht); * In case of successful operation, smp_wmb() is implied before the pointer is * inserted into the hash table. * - * Returns true on sucess. + * Returns true on success. * Returns false if the @p-@hash pair already exists in the hash table. */ bool qht_insert(struct qht *ht, void *p, uint32_t hash); diff --git a/include/qemu/queue.h b/include/qemu/queue.h index 342073fb4d..35292c3155 100644 --- a/include/qemu/queue.h +++ b/include/qemu/queue.h @@ -438,4 +438,64 @@ struct { \ #define QTAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define field_at_offset(base, offset, type) \ + ((type) (((char *) (base)) + (offset))) + +typedef struct DUMMY_Q_ENTRY DUMMY_Q_ENTRY; +typedef struct DUMMY_Q DUMMY_Q; + +struct DUMMY_Q_ENTRY { + QTAILQ_ENTRY(DUMMY_Q_ENTRY) next; +}; + +struct DUMMY_Q { + QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY) head; +}; + +#define dummy_q ((DUMMY_Q *) 0) +#define dummy_qe ((DUMMY_Q_ENTRY *) 0) + +/* + * Offsets of layout of a tail queue head. + */ +#define QTAILQ_FIRST_OFFSET (offsetof(typeof(dummy_q->head), tqh_first)) +#define QTAILQ_LAST_OFFSET (offsetof(typeof(dummy_q->head), tqh_last)) +/* + * Raw access of elements of a tail queue + */ +#define QTAILQ_RAW_FIRST(head) \ + (*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **)) +#define QTAILQ_RAW_TQH_LAST(head) \ + (*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***)) + +/* + * Offsets of layout of a tail queue element. + */ +#define QTAILQ_NEXT_OFFSET (offsetof(typeof(dummy_qe->next), tqe_next)) +#define QTAILQ_PREV_OFFSET (offsetof(typeof(dummy_qe->next), tqe_prev)) + +/* + * Raw access of elements of a tail entry + */ +#define QTAILQ_RAW_NEXT(elm, entry) \ + (*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **)) +#define QTAILQ_RAW_TQE_PREV(elm, entry) \ + (*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***)) +/* + * Tail queue tranversal using pointer arithmetic. + */ +#define QTAILQ_RAW_FOREACH(elm, head, entry) \ + for ((elm) = QTAILQ_RAW_FIRST(head); \ + (elm); \ + (elm) = QTAILQ_RAW_NEXT(elm, entry)) +/* + * Tail queue insertion using pointer arithmetic. + */ +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do { \ + QTAILQ_RAW_NEXT(elm, entry) = NULL; \ + QTAILQ_RAW_TQE_PREV(elm, entry) = QTAILQ_RAW_TQH_LAST(head); \ + *QTAILQ_RAW_TQH_LAST(head) = (elm); \ + QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry); \ +} while (/*CONSTCOND*/0) + #endif /* QEMU_SYS_QUEUE_H */ diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 5589e6842b..5f1bab9b3e 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -32,6 +32,8 @@ int socket_set_fast_reuse(int fd); */ typedef void NonBlockingConnectHandler(int fd, Error *err, void *opaque); +int inet_ai_family_from_address(InetSocketAddress *addr, + Error **errp); InetSocketAddress *inet_parse(const char *str, Error **errp); int inet_connect(const char *str, Error **errp); int inet_connect_saddr(InetSocketAddress *saddr, Error **errp, diff --git a/include/qemu/thread.h b/include/qemu/thread.h index e8e665f020..9910f49b3a 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -8,6 +8,7 @@ typedef struct QemuMutex QemuMutex; typedef struct QemuCond QemuCond; typedef struct QemuSemaphore QemuSemaphore; typedef struct QemuEvent QemuEvent; +typedef struct QemuLockCnt QemuLockCnt; typedef struct QemuThread QemuThread; #ifdef _WIN32 @@ -98,4 +99,115 @@ static inline void qemu_spin_unlock(QemuSpin *spin) __sync_lock_release(&spin->value); } +struct QemuLockCnt { +#ifndef CONFIG_LINUX + QemuMutex mutex; +#endif + unsigned count; +}; + +/** + * qemu_lockcnt_init: initialize a QemuLockcnt + * @lockcnt: the lockcnt to initialize + * + * Initialize lockcnt's counter to zero and prepare its mutex + * for usage. + */ +void qemu_lockcnt_init(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_destroy: destroy a QemuLockcnt + * @lockcnt: the lockcnt to destruct + * + * Destroy lockcnt's mutex. + */ +void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc: increment a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + * + * If the lockcnt's count is zero, wait for critical sections + * to finish and increment lockcnt's count to 1. If the count + * is not zero, just increment it. + * + * Because this function can wait on the mutex, it must not be + * called while the lockcnt's mutex is held by the current thread. + * For the same reason, qemu_lockcnt_inc can also contribute to + * AB-BA deadlocks. This is a sample deadlock scenario: + * + * thread 1 thread 2 + * ------------------------------------------------------- + * qemu_lockcnt_lock(&lc1); + * qemu_lockcnt_lock(&lc2); + * qemu_lockcnt_inc(&lc2); + * qemu_lockcnt_inc(&lc1); + */ +void qemu_lockcnt_inc(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec: decrement a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + */ +void qemu_lockcnt_dec(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and + * possibly lock it. + * @lockcnt: the lockcnt to operate on + * + * Decrement lockcnt's count. If the new count is zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and + * lock it. + * @lockcnt: the lockcnt to operate on + * + * If the count is 1, decrement the count to zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_lock: lock a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on + * + * Remember that concurrent visits are not blocked unless the count is + * also zero. You can use qemu_lockcnt_count to check for this inside a + * critical section. + */ +void qemu_lockcnt_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_unlock: release a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on. + */ +void qemu_lockcnt_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt. + * @lockcnt: the lockcnt to operate on. + * + * This is the same as + * + * qemu_lockcnt_unlock(lockcnt); + * qemu_lockcnt_inc(lockcnt); + * + * but more efficient. + */ +void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_count: query a LockCnt's count. + * @lockcnt: the lockcnt to query. + * + * Note that the count can change at any time. Still, while the + * lockcnt is locked, one can usefully check whether the count + * is non-zero. + */ +unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt); + #endif diff --git a/include/qemu/xattr.h b/include/qemu/xattr.h index 83cf98cbd8..a83fe8e749 100644 --- a/include/qemu/xattr.h +++ b/include/qemu/xattr.h @@ -14,7 +14,7 @@ #define QEMU_XATTR_H /* - * Modern distributions (e.g. Fedora 15, have no libattr.so, place attr.h + * Modern distributions (e.g. Fedora 15), have no libattr.so, place attr.h * in /usr/include/sys, and don't have ENOATTR. */ |