From nobody Tue Feb 10 00:59:28 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1492176078803428.96798405559593; Fri, 14 Apr 2017 06:21:18 -0700 (PDT) Received: from localhost ([::1]:53292 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cz1A5-0001V6-ER for importer@patchew.org; Fri, 14 Apr 2017 09:21:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49162) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cz16h-0007R1-LT for qemu-devel@nongnu.org; Fri, 14 Apr 2017 09:17:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cz16e-0008DZ-8V for qemu-devel@nongnu.org; Fri, 14 Apr 2017 09:17:47 -0400 Received: from mailout4.w1.samsung.com ([210.118.77.14]:11705) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cz16d-0008C9-Vk for qemu-devel@nongnu.org; Fri, 14 Apr 2017 09:17:44 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OOE00BOTI9GRT00@mailout4.w1.samsung.com> for qemu-devel@nongnu.org; Fri, 14 Apr 2017 14:17:40 +0100 (BST) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170414131740eucas1p1d4c8ccb2ee782d452cf590d74dd986f8~1Rgnw_7yc1011710117eucas1p1Q; Fri, 14 Apr 2017 13:17:40 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 0A.D9.25577.3FBC0F85; Fri, 14 Apr 2017 14:17:39 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170414131739eucas1p1ea9a6adcdbe8cfe45ac1ff582d28d873~1RgnExbIW1972019720eucas1p10; Fri, 14 Apr 2017 13:17:39 +0000 (GMT) Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 96.FF.20206.90CC0F85; Fri, 14 Apr 2017 14:18:01 +0100 (BST) Received: from aperevalov-ubuntu.rnd.samsung.ru ([106.109.129.199]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OOE00KVHI9AY150@eusync2.samsung.com>; Fri, 14 Apr 2017 14:17:39 +0100 (BST) X-AuditID: cbfec7f5-f792f6d0000063e9-22-58f0cbf3a03c From: Alexey Perevalov To: dgilbert@redhat.com, qemu-devel@nongnu.org Date: Fri, 14 Apr 2017 16:17:16 +0300 Message-id: <1492175840-5021-3-git-send-email-a.perevalov@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1492175840-5021-1-git-send-email-a.perevalov@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrEIsWRmVeSWpSXmKPExsWy7djPc7qfT3+IMPj91MBi7t3zLBa92+6x W1xp/8lucbx3B4sDi8eTa5uZPN7vu8rm0bdlFWMAcxSXTUpqTmZZapG+XQJXxp3fJ1kKPr9n rOh+dZK9gXHTQsYuRk4OCQETia8fnkLZYhIX7q1n62Lk4hASWMoo8ebBKmYI5zOjxJ7mKaww HQe6L0BVLWOUmP5kBjuE080kcezXJpYuRg4ONgEDiX33bEEaRAT0JK586wRbwSxgLNHy8zk7 iC0sYCTxae8zMJtFQFXi3qNWZhCbV8BN4teqdhaIZXISJ49NBlvMKeAu8erHShaQXRICZ9gk PnXsYAbZJSEgK7HpAJTpInH9fiJEq7DEq+Nb2CFsGYnLk7uhWtsZJbp3drJCOBMYJc5M/wtV ZS9x6uZVJohD+SQmbZsONZRXoqNNCKLEQ2LxgteMEGFHia13MiFen8Uo0XqqiWUCo8wCRoZV jCKppcW56anFpnrFibnFpXnpesn5uZsYgTF5+t/xrzsYlx6zOsQowMGoxMN74fiHCCHWxLLi ytxDjBIczEoivNGngEK8KYmVValF+fFFpTmpxYcYpTlYlMR5uU5dixASSE8sSc1OTS1ILYLJ MnFwSjUwrllTtc0/OtiWMckuMpjJ0E9hvTrjNlHb2c8Kbm1cv3Lbv61n/N30HCdKqjh0nJWe dGyFtPKi5QxvZp2Z9aHgtjK72Zlf896UCRYXbK3bPKtCWu74ctvTum8tfr+/vjwtfmbP3EMT Pe0Xv1XjVhc5MjudoXTJXdPI7MV/KzSbH+60aGJcNUmCVYmlOCPRUIu5qDgRABz1GBLFAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrELMWRmVeSWpSXmKPExsVy+t/xK7qcZz5EGKxdZ24x9+55FovebffY La60/2S3ON67g8WBxePJtc1MHu/3XWXz6NuyijGAOcrNJiM1MSW1SCE1Lzk/JTMv3VYpNMRN 10JJIS8xN9VWKULXNyRISaEsMacUyDMyQAMOzgHuwUr6dgluGXd+n2Qp+PyesaL71Un2BsZN Cxm7GDk5JARMJA50X2CDsMUkLtxbD2RzcQgJLGGUmL+rBcrpZZJY+f0eexcjBwebgIHEvnu2 IA0iAnoSV751gg1iFjCWaPn5nB3EFhYwkvi09xmYzSKgKnHvUSsziM0r4Cbxa1U7C8QyOYmT xyazgticAu4Sr36sBIsLAdWsPP2eaQIj7wJGhlWMIqmlxbnpucVGesWJucWleel6yfm5mxiB 4bnt2M8tOxi73gUfYhTgYFTi4a04+iFCiDWxrLgy9xCjBAezkghv9CmgEG9KYmVValF+fFFp TmrxIUZToKMmMkuJJucDYyevJN7QxNDc0tDI2MLC3MhISZx36ocr4UIC6YklqdmpqQWpRTB9 TBycUg2MkfYiU8q4D38+6rlBK3H+8uRHN9KTN6ot2H8/05lPInnSi/AphZwrQy+ZcAQZV6sV NittMcmOzLhk7juH9W7g7sldwuca1jKwRV804L51cv3ed+zcFx3PqNgsPD4tV33O+b5IN6GW SuXWdyFz7HXrE7r9ZdXS1604Mj0ssD74qtcuN6+5V0OUWIozEg21mIuKEwHXW1yeZQIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170414131739eucas1p1ea9a6adcdbe8cfe45ac1ff582d28d873 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?QWxleGV5IFBlcmV2YWxvdhtTUlItVmlydHVhbGl6YXRpb24g?= =?UTF-8?B?TGFiG+yCvOyEseyghOyekBtTZW5pb3IgRW5naW5lZXI=?= X-Global-Sender: =?UTF-8?B?QWxleGV5IFBlcmV2YWxvdhtTUlItVmlydHVhbGl6YXRpb24g?= =?UTF-8?B?TGFiG1NhbXN1bmcgRWxlY3Ryb25pY3MbU2VuaW9yIEVuZ2luZWVy?= X-Sender-Code: =?UTF-8?B?QzEwG0NJU0hRG0MxMEdEMDFHRDAxMDE1NA==?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170414131739eucas1p1ea9a6adcdbe8cfe45ac1ff582d28d873 X-RootMTR: 20170414131739eucas1p1ea9a6adcdbe8cfe45ac1ff582d28d873 References: <1492175840-5021-1-git-send-email-a.perevalov@samsung.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 210.118.77.14 Subject: [Qemu-devel] [PATCH 2/6] util: introduce glib-helper.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: i.maximets@samsung.com, a.perevalov@samsung.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" There is a lack of g_int_cmp which compares pointers value in glib, xen_disk.c introduced its own, so the same function now requires in migration.c. So logically to move it into common place. Futher: maybe extend glib. Also this commit moves existing glib-compat.h into util/glib folder for consolidation purpose. Signed-off-by: Alexey Perevalov --- hw/block/xen_disk.c | 10 +- include/glib-compat.h | 352 -----------------------------------------= ---- include/glib/glib-compat.h | 352 +++++++++++++++++++++++++++++++++++++++++= ++++ include/glib/glib-helper.h | 30 ++++ include/qemu/osdep.h | 2 +- linux-user/main.c | 2 +- scripts/clean-includes | 2 +- util/Makefile.objs | 1 + util/glib-helper.c | 29 ++++ 9 files changed, 417 insertions(+), 363 deletions(-) delete mode 100644 include/glib-compat.h create mode 100644 include/glib/glib-compat.h create mode 100644 include/glib/glib-helper.h create mode 100644 util/glib-helper.c diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 456a2d5..36f6396 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -20,6 +20,7 @@ */ =20 #include "qemu/osdep.h" +#include "glib/glib-helper.h" #include #include =20 @@ -154,13 +155,6 @@ static void ioreq_reset(struct ioreq *ioreq) qemu_iovec_reset(&ioreq->v); } =20 -static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data) -{ - uint ua =3D GPOINTER_TO_UINT(a); - uint ub =3D GPOINTER_TO_UINT(b); - return (ua > ub) - (ua < ub); -} - static void destroy_grant(gpointer pgnt) { PersistentGrant *grant =3D pgnt; @@ -1191,7 +1185,7 @@ static int blk_connect(struct XenDevice *xendev) if (blkdev->feature_persistent) { /* Init persistent grants */ blkdev->max_grants =3D max_requests * BLKIF_MAX_SEGMENTS_PER_REQUE= ST; - blkdev->persistent_gnts =3D g_tree_new_full((GCompareDataFunc)int_= cmp, + blkdev->persistent_gnts =3D g_tree_new_full((GCompareDataFunc)g_in= t_cmp, NULL, NULL, batch_maps ? (GDestroyNotify)g_free : diff --git a/include/glib-compat.h b/include/glib-compat.h deleted file mode 100644 index 863c8cf..0000000 --- a/include/glib-compat.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * GLIB Compatibility Functions - * - * Copyright IBM, Corp. 2013 - * - * Authors: - * Anthony Liguori - * Michael Tokarev - * Paolo Bonzini - * - * This work is licensed under the terms of the GNU GPL, version 2 or late= r. - * See the COPYING file in the top-level directory. - * - */ - -#ifndef QEMU_GLIB_COMPAT_H -#define QEMU_GLIB_COMPAT_H - -#include - -/* GLIB version compatibility flags */ -#if !GLIB_CHECK_VERSION(2, 26, 0) -#define G_TIME_SPAN_SECOND (G_GINT64_CONSTANT(1000000)) -#endif - -#if !GLIB_CHECK_VERSION(2, 28, 0) -static inline gint64 qemu_g_get_monotonic_time(void) -{ - /* g_get_monotonic_time() is best-effort so we can use the wall clock = as a - * fallback. - */ - - GTimeVal time; - g_get_current_time(&time); - - return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec; -} -/* work around distro backports of this interface */ -#define g_get_monotonic_time() qemu_g_get_monotonic_time() -#endif - -#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0) -/* - * g_poll has a problem on Windows when using - * timeouts < 10ms, so use wrapper. - */ -#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout) -gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); -#endif - -#if !GLIB_CHECK_VERSION(2, 30, 0) -/* Not a 100% compatible implementation, but good enough for most - * cases. Placeholders are only supported at the end of the - * template. */ -static inline gchar *qemu_g_dir_make_tmp(gchar const *tmpl, GError **error) -{ - gchar *path =3D g_build_filename(g_get_tmp_dir(), tmpl ?: ".XXXXXX", N= ULL); - - if (mkdtemp(path) !=3D NULL) { - return path; - } - /* Error occurred, clean up. */ - g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), - "mkdtemp() failed"); - g_free(path); - return NULL; -} -#define g_dir_make_tmp(tmpl, error) qemu_g_dir_make_tmp(tmpl, error) -#endif /* glib 2.30 */ - -#if !GLIB_CHECK_VERSION(2, 31, 0) -/* before glib-2.31, GMutex and GCond was dynamic-only (there was a separa= te - * GStaticMutex, but it didn't work with condition variables). - * - * Our implementation uses GOnce to fake a static implementation that does - * not require separate initialization. - * We need to rename the types to avoid passing our CompatGMutex/CompatGCo= nd - * by mistake to a function that expects GMutex/GCond. However, for ease - * of use we keep the GLib function names. GLib uses macros for the - * implementation, we use inline functions instead and undefine the macros. - */ - -typedef struct CompatGMutex { - GOnce once; -} CompatGMutex; - -typedef struct CompatGCond { - GOnce once; -} CompatGCond; - -static inline gpointer do_g_mutex_new(gpointer unused) -{ - return (gpointer) g_mutex_new(); -} - -static inline void g_mutex_init(CompatGMutex *mutex) -{ - mutex->once =3D (GOnce) G_ONCE_INIT; -} - -static inline void g_mutex_clear(CompatGMutex *mutex) -{ - g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); - if (mutex->once.retval) { - g_mutex_free((GMutex *) mutex->once.retval); - } - mutex->once =3D (GOnce) G_ONCE_INIT; -} - -static inline void (g_mutex_lock)(CompatGMutex *mutex) -{ - g_once(&mutex->once, do_g_mutex_new, NULL); - g_mutex_lock((GMutex *) mutex->once.retval); -} -#undef g_mutex_lock - -static inline gboolean (g_mutex_trylock)(CompatGMutex *mutex) -{ - g_once(&mutex->once, do_g_mutex_new, NULL); - return g_mutex_trylock((GMutex *) mutex->once.retval); -} -#undef g_mutex_trylock - - -static inline void (g_mutex_unlock)(CompatGMutex *mutex) -{ - g_mutex_unlock((GMutex *) mutex->once.retval); -} -#undef g_mutex_unlock - -static inline gpointer do_g_cond_new(gpointer unused) -{ - return (gpointer) g_cond_new(); -} - -static inline void g_cond_init(CompatGCond *cond) -{ - cond->once =3D (GOnce) G_ONCE_INIT; -} - -static inline void g_cond_clear(CompatGCond *cond) -{ - g_assert(cond->once.status !=3D G_ONCE_STATUS_PROGRESS); - if (cond->once.retval) { - g_cond_free((GCond *) cond->once.retval); - } - cond->once =3D (GOnce) G_ONCE_INIT; -} - -static inline void (g_cond_wait)(CompatGCond *cond, CompatGMutex *mutex) -{ - g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); - g_once(&cond->once, do_g_cond_new, NULL); - g_cond_wait((GCond *) cond->once.retval, (GMutex *) mutex->once.retval= ); -} -#undef g_cond_wait - -static inline void (g_cond_broadcast)(CompatGCond *cond) -{ - g_once(&cond->once, do_g_cond_new, NULL); - g_cond_broadcast((GCond *) cond->once.retval); -} -#undef g_cond_broadcast - -static inline void (g_cond_signal)(CompatGCond *cond) -{ - g_once(&cond->once, do_g_cond_new, NULL); - g_cond_signal((GCond *) cond->once.retval); -} -#undef g_cond_signal - -static inline gboolean (g_cond_timed_wait)(CompatGCond *cond, - CompatGMutex *mutex, - GTimeVal *time) -{ - g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); - g_once(&cond->once, do_g_cond_new, NULL); - return g_cond_timed_wait((GCond *) cond->once.retval, - (GMutex *) mutex->once.retval, time); -} -#undef g_cond_timed_wait - -/* This is not a macro, because it didn't exist until 2.32. */ -static inline gboolean g_cond_wait_until(CompatGCond *cond, CompatGMutex *= mutex, - gint64 end_time) -{ - GTimeVal time; - - /* Convert from monotonic to CLOCK_REALTIME. */ - end_time -=3D g_get_monotonic_time(); - g_get_current_time(&time); - end_time +=3D time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec; - - time.tv_sec =3D end_time / G_TIME_SPAN_SECOND; - time.tv_usec =3D end_time % G_TIME_SPAN_SECOND; - return g_cond_timed_wait(cond, mutex, &time); -} - -/* before 2.31 there was no g_thread_new() */ -static inline GThread *g_thread_new(const char *name, - GThreadFunc func, gpointer data) -{ - GThread *thread =3D g_thread_create(func, data, TRUE, NULL); - if (!thread) { - g_error("creating thread"); - } - return thread; -} -#else -#define CompatGMutex GMutex -#define CompatGCond GCond -#endif /* glib 2.31 */ - -#if !GLIB_CHECK_VERSION(2, 32, 0) -/* Beware, function returns gboolean since 2.39.2, see GLib commit 9101915= */ -static inline void g_hash_table_add(GHashTable *hash_table, gpointer key) -{ - g_hash_table_replace(hash_table, key, key); -} -#endif - -#ifndef g_assert_true -#define g_assert_true(expr) = \ - do { = \ - if (G_LIKELY(expr)) { = \ - } else { = \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ - "'" #expr "' should be TRUE"); = \ - } = \ - } while (0) -#endif - -#ifndef g_assert_false -#define g_assert_false(expr) = \ - do { = \ - if (G_LIKELY(!(expr))) { = \ - } else { = \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ - "'" #expr "' should be FALSE"); = \ - } = \ - } while (0) -#endif - -#ifndef g_assert_null -#define g_assert_null(expr) = \ - do { = \ - if (G_LIKELY((expr) =3D=3D NULL)) { = \ - } else { = \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ - "'" #expr "' should be NULL"); = \ - } = \ - } while (0) -#endif - -#ifndef g_assert_nonnull -#define g_assert_nonnull(expr) = \ - do { = \ - if (G_LIKELY((expr) !=3D NULL)) { = \ - } else { = \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ - "'" #expr "' should not be NULL"); = \ - } = \ - } while (0) -#endif - -#ifndef g_assert_cmpmem -#define g_assert_cmpmem(m1, l1, m2, l2) = \ - do { = \ - gconstpointer __m1 =3D m1, __m2 =3D m2; = \ - int __l1 =3D l1, __l2 =3D l2; = \ - if (__l1 !=3D __l2) { = \ - g_assertion_message_cmpnum( = \ - G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, = \ - #l1 " (len(" #m1 ")) =3D=3D " #l2 " (len(" #m2 "))", __l1,= "=3D=3D", \ - __l2, 'i'); = \ - } else if (memcmp(__m1, __m2, __l1) !=3D 0) { = \ - g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ - "assertion failed (" #m1 " =3D=3D " #m2 ")= "); \ - } = \ - } while (0) -#endif - -#if !GLIB_CHECK_VERSION(2, 28, 0) -static inline void g_list_free_full(GList *list, GDestroyNotify free_func) -{ - GList *l; - - for (l =3D list; l; l =3D l->next) { - free_func(l->data); - } - - g_list_free(list); -} - -static inline void g_slist_free_full(GSList *list, GDestroyNotify free_fun= c) -{ - GSList *l; - - for (l =3D list; l; l =3D l->next) { - free_func(l->data); - } - - g_slist_free(list); -} -#endif - -#if !GLIB_CHECK_VERSION(2, 26, 0) -static inline void g_source_set_name(GSource *source, const char *name) -{ - /* This is just a debugging aid, so leaving it a no-op */ -} -static inline void g_source_set_name_by_id(guint tag, const char *name) -{ - /* This is just a debugging aid, so leaving it a no-op */ -} -#endif - -#if !GLIB_CHECK_VERSION(2, 36, 0) -/* Always fail. This will not include error_report output in the test log, - * sending it instead to stderr. - */ -#define g_test_initialized() (0) -#endif -#if !GLIB_CHECK_VERSION(2, 38, 0) -#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS -#error schizophrenic detection of glib subprocess testing -#endif -#define g_test_subprocess() (0) -#endif - - -#if !GLIB_CHECK_VERSION(2, 34, 0) -static inline void -g_test_add_data_func_full(const char *path, - gpointer data, - gpointer fn, - gpointer data_free_func) -{ -#if GLIB_CHECK_VERSION(2, 26, 0) - /* back-compat casts, remove this once we can require new-enough glib = */ - g_test_add_vtable(path, 0, data, NULL, - (GTestFixtureFunc)fn, (GTestFixtureFunc) data_free_f= unc); -#else - /* back-compat casts, remove this once we can require new-enough glib = */ - g_test_add_vtable(path, 0, data, NULL, - (void (*)(void)) fn, (void (*)(void)) data_free_func= ); -#endif -} -#endif - - -#endif diff --git a/include/glib/glib-compat.h b/include/glib/glib-compat.h new file mode 100644 index 0000000..863c8cf --- /dev/null +++ b/include/glib/glib-compat.h @@ -0,0 +1,352 @@ +/* + * GLIB Compatibility Functions + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Anthony Liguori + * Michael Tokarev + * Paolo Bonzini + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_GLIB_COMPAT_H +#define QEMU_GLIB_COMPAT_H + +#include + +/* GLIB version compatibility flags */ +#if !GLIB_CHECK_VERSION(2, 26, 0) +#define G_TIME_SPAN_SECOND (G_GINT64_CONSTANT(1000000)) +#endif + +#if !GLIB_CHECK_VERSION(2, 28, 0) +static inline gint64 qemu_g_get_monotonic_time(void) +{ + /* g_get_monotonic_time() is best-effort so we can use the wall clock = as a + * fallback. + */ + + GTimeVal time; + g_get_current_time(&time); + + return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec; +} +/* work around distro backports of this interface */ +#define g_get_monotonic_time() qemu_g_get_monotonic_time() +#endif + +#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0) +/* + * g_poll has a problem on Windows when using + * timeouts < 10ms, so use wrapper. + */ +#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout) +gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout); +#endif + +#if !GLIB_CHECK_VERSION(2, 30, 0) +/* Not a 100% compatible implementation, but good enough for most + * cases. Placeholders are only supported at the end of the + * template. */ +static inline gchar *qemu_g_dir_make_tmp(gchar const *tmpl, GError **error) +{ + gchar *path =3D g_build_filename(g_get_tmp_dir(), tmpl ?: ".XXXXXX", N= ULL); + + if (mkdtemp(path) !=3D NULL) { + return path; + } + /* Error occurred, clean up. */ + g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), + "mkdtemp() failed"); + g_free(path); + return NULL; +} +#define g_dir_make_tmp(tmpl, error) qemu_g_dir_make_tmp(tmpl, error) +#endif /* glib 2.30 */ + +#if !GLIB_CHECK_VERSION(2, 31, 0) +/* before glib-2.31, GMutex and GCond was dynamic-only (there was a separa= te + * GStaticMutex, but it didn't work with condition variables). + * + * Our implementation uses GOnce to fake a static implementation that does + * not require separate initialization. + * We need to rename the types to avoid passing our CompatGMutex/CompatGCo= nd + * by mistake to a function that expects GMutex/GCond. However, for ease + * of use we keep the GLib function names. GLib uses macros for the + * implementation, we use inline functions instead and undefine the macros. + */ + +typedef struct CompatGMutex { + GOnce once; +} CompatGMutex; + +typedef struct CompatGCond { + GOnce once; +} CompatGCond; + +static inline gpointer do_g_mutex_new(gpointer unused) +{ + return (gpointer) g_mutex_new(); +} + +static inline void g_mutex_init(CompatGMutex *mutex) +{ + mutex->once =3D (GOnce) G_ONCE_INIT; +} + +static inline void g_mutex_clear(CompatGMutex *mutex) +{ + g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); + if (mutex->once.retval) { + g_mutex_free((GMutex *) mutex->once.retval); + } + mutex->once =3D (GOnce) G_ONCE_INIT; +} + +static inline void (g_mutex_lock)(CompatGMutex *mutex) +{ + g_once(&mutex->once, do_g_mutex_new, NULL); + g_mutex_lock((GMutex *) mutex->once.retval); +} +#undef g_mutex_lock + +static inline gboolean (g_mutex_trylock)(CompatGMutex *mutex) +{ + g_once(&mutex->once, do_g_mutex_new, NULL); + return g_mutex_trylock((GMutex *) mutex->once.retval); +} +#undef g_mutex_trylock + + +static inline void (g_mutex_unlock)(CompatGMutex *mutex) +{ + g_mutex_unlock((GMutex *) mutex->once.retval); +} +#undef g_mutex_unlock + +static inline gpointer do_g_cond_new(gpointer unused) +{ + return (gpointer) g_cond_new(); +} + +static inline void g_cond_init(CompatGCond *cond) +{ + cond->once =3D (GOnce) G_ONCE_INIT; +} + +static inline void g_cond_clear(CompatGCond *cond) +{ + g_assert(cond->once.status !=3D G_ONCE_STATUS_PROGRESS); + if (cond->once.retval) { + g_cond_free((GCond *) cond->once.retval); + } + cond->once =3D (GOnce) G_ONCE_INIT; +} + +static inline void (g_cond_wait)(CompatGCond *cond, CompatGMutex *mutex) +{ + g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); + g_once(&cond->once, do_g_cond_new, NULL); + g_cond_wait((GCond *) cond->once.retval, (GMutex *) mutex->once.retval= ); +} +#undef g_cond_wait + +static inline void (g_cond_broadcast)(CompatGCond *cond) +{ + g_once(&cond->once, do_g_cond_new, NULL); + g_cond_broadcast((GCond *) cond->once.retval); +} +#undef g_cond_broadcast + +static inline void (g_cond_signal)(CompatGCond *cond) +{ + g_once(&cond->once, do_g_cond_new, NULL); + g_cond_signal((GCond *) cond->once.retval); +} +#undef g_cond_signal + +static inline gboolean (g_cond_timed_wait)(CompatGCond *cond, + CompatGMutex *mutex, + GTimeVal *time) +{ + g_assert(mutex->once.status !=3D G_ONCE_STATUS_PROGRESS); + g_once(&cond->once, do_g_cond_new, NULL); + return g_cond_timed_wait((GCond *) cond->once.retval, + (GMutex *) mutex->once.retval, time); +} +#undef g_cond_timed_wait + +/* This is not a macro, because it didn't exist until 2.32. */ +static inline gboolean g_cond_wait_until(CompatGCond *cond, CompatGMutex *= mutex, + gint64 end_time) +{ + GTimeVal time; + + /* Convert from monotonic to CLOCK_REALTIME. */ + end_time -=3D g_get_monotonic_time(); + g_get_current_time(&time); + end_time +=3D time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec; + + time.tv_sec =3D end_time / G_TIME_SPAN_SECOND; + time.tv_usec =3D end_time % G_TIME_SPAN_SECOND; + return g_cond_timed_wait(cond, mutex, &time); +} + +/* before 2.31 there was no g_thread_new() */ +static inline GThread *g_thread_new(const char *name, + GThreadFunc func, gpointer data) +{ + GThread *thread =3D g_thread_create(func, data, TRUE, NULL); + if (!thread) { + g_error("creating thread"); + } + return thread; +} +#else +#define CompatGMutex GMutex +#define CompatGCond GCond +#endif /* glib 2.31 */ + +#if !GLIB_CHECK_VERSION(2, 32, 0) +/* Beware, function returns gboolean since 2.39.2, see GLib commit 9101915= */ +static inline void g_hash_table_add(GHashTable *hash_table, gpointer key) +{ + g_hash_table_replace(hash_table, key, key); +} +#endif + +#ifndef g_assert_true +#define g_assert_true(expr) = \ + do { = \ + if (G_LIKELY(expr)) { = \ + } else { = \ + g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ + "'" #expr "' should be TRUE"); = \ + } = \ + } while (0) +#endif + +#ifndef g_assert_false +#define g_assert_false(expr) = \ + do { = \ + if (G_LIKELY(!(expr))) { = \ + } else { = \ + g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ + "'" #expr "' should be FALSE"); = \ + } = \ + } while (0) +#endif + +#ifndef g_assert_null +#define g_assert_null(expr) = \ + do { = \ + if (G_LIKELY((expr) =3D=3D NULL)) { = \ + } else { = \ + g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ + "'" #expr "' should be NULL"); = \ + } = \ + } while (0) +#endif + +#ifndef g_assert_nonnull +#define g_assert_nonnull(expr) = \ + do { = \ + if (G_LIKELY((expr) !=3D NULL)) { = \ + } else { = \ + g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ + "'" #expr "' should not be NULL"); = \ + } = \ + } while (0) +#endif + +#ifndef g_assert_cmpmem +#define g_assert_cmpmem(m1, l1, m2, l2) = \ + do { = \ + gconstpointer __m1 =3D m1, __m2 =3D m2; = \ + int __l1 =3D l1, __l2 =3D l2; = \ + if (__l1 !=3D __l2) { = \ + g_assertion_message_cmpnum( = \ + G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, = \ + #l1 " (len(" #m1 ")) =3D=3D " #l2 " (len(" #m2 "))", __l1,= "=3D=3D", \ + __l2, 'i'); = \ + } else if (memcmp(__m1, __m2, __l1) !=3D 0) { = \ + g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUN= C, \ + "assertion failed (" #m1 " =3D=3D " #m2 ")= "); \ + } = \ + } while (0) +#endif + +#if !GLIB_CHECK_VERSION(2, 28, 0) +static inline void g_list_free_full(GList *list, GDestroyNotify free_func) +{ + GList *l; + + for (l =3D list; l; l =3D l->next) { + free_func(l->data); + } + + g_list_free(list); +} + +static inline void g_slist_free_full(GSList *list, GDestroyNotify free_fun= c) +{ + GSList *l; + + for (l =3D list; l; l =3D l->next) { + free_func(l->data); + } + + g_slist_free(list); +} +#endif + +#if !GLIB_CHECK_VERSION(2, 26, 0) +static inline void g_source_set_name(GSource *source, const char *name) +{ + /* This is just a debugging aid, so leaving it a no-op */ +} +static inline void g_source_set_name_by_id(guint tag, const char *name) +{ + /* This is just a debugging aid, so leaving it a no-op */ +} +#endif + +#if !GLIB_CHECK_VERSION(2, 36, 0) +/* Always fail. This will not include error_report output in the test log, + * sending it instead to stderr. + */ +#define g_test_initialized() (0) +#endif +#if !GLIB_CHECK_VERSION(2, 38, 0) +#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS +#error schizophrenic detection of glib subprocess testing +#endif +#define g_test_subprocess() (0) +#endif + + +#if !GLIB_CHECK_VERSION(2, 34, 0) +static inline void +g_test_add_data_func_full(const char *path, + gpointer data, + gpointer fn, + gpointer data_free_func) +{ +#if GLIB_CHECK_VERSION(2, 26, 0) + /* back-compat casts, remove this once we can require new-enough glib = */ + g_test_add_vtable(path, 0, data, NULL, + (GTestFixtureFunc)fn, (GTestFixtureFunc) data_free_f= unc); +#else + /* back-compat casts, remove this once we can require new-enough glib = */ + g_test_add_vtable(path, 0, data, NULL, + (void (*)(void)) fn, (void (*)(void)) data_free_func= ); +#endif +} +#endif + + +#endif diff --git a/include/glib/glib-helper.h b/include/glib/glib-helper.h new file mode 100644 index 0000000..db740fb --- /dev/null +++ b/include/glib/glib-helper.h @@ -0,0 +1,30 @@ +/* + * Helpers for GLIB + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_GLIB_HELPER_H +#define QEMU_GLIB_HELPER_H + + +#include "glib/glib-compat.h" + +#define GPOINTER_TO_UINT64(a) ((guint64) (a)) + +/* + * return 1 in case of a > b, -1 otherwise and 0 if equeal + */ +gint g_int_cmp64(gconstpointer a, gconstpointer b, + gpointer __attribute__((unused)) user_data); + +/* + * return 1 in case of a > b, -1 otherwise and 0 if equeal + */ +int g_int_cmp(gconstpointer a, gconstpointer b, + gpointer __attribute__((unused)) user_data); + +#endif /* QEMU_GLIB_HELPER_H */ + diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 122ff06..36f8a89 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -104,7 +104,7 @@ extern int daemon(int, int); #include "sysemu/os-posix.h" #endif =20 -#include "glib-compat.h" +#include "glib/glib-compat.h" #include "qemu/typedefs.h" =20 #ifndef O_LARGEFILE diff --git a/linux-user/main.c b/linux-user/main.c index 10a3bb3..7cea6bc 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -35,7 +35,7 @@ #include "elf.h" #include "exec/log.h" #include "trace/control.h" -#include "glib-compat.h" +#include "glib/glib-compat.h" =20 char *exec_path; =20 diff --git a/scripts/clean-includes b/scripts/clean-includes index dd938da..b32b928 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -123,7 +123,7 @@ for f in "$@"; do ;; *include/qemu/osdep.h | \ *include/qemu/compiler.h | \ - *include/glib-compat.h | \ + *include/glib/glib-compat.h | \ *include/sysemu/os-posix.h | \ *include/sysemu/os-win32.h | \ *include/standard-headers/ ) diff --git a/util/Makefile.objs b/util/Makefile.objs index c6205eb..0080712 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -43,3 +43,4 @@ util-obj-y +=3D qdist.o util-obj-y +=3D qht.o util-obj-y +=3D range.o util-obj-y +=3D systemd.o +util-obj-y +=3D glib-helper.o diff --git a/util/glib-helper.c b/util/glib-helper.c new file mode 100644 index 0000000..2557009 --- /dev/null +++ b/util/glib-helper.c @@ -0,0 +1,29 @@ +/* + * Implementation for GLIB helpers + * this file is intented to commulate and later reuse + * additional glib functions + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + + */ + +#include "glib/glib-helper.h" + +gint g_int_cmp64(gconstpointer a, gconstpointer b, + gpointer __attribute__((unused)) user_data) +{ + guint64 ua =3D GPOINTER_TO_UINT64(a); + guint64 ub =3D GPOINTER_TO_UINT64(b); + return (ua > ub) - (ua < ub); +} + +/* + * return 1 in case of a > b, -1 otherwise and 0 if equeal + */ +gint g_int_cmp(gconstpointer a, gconstpointer b, + gpointer __attribute__((unused)) user_data) +{ + return g_int_cmp64(a, b, user_data); +} + --=20 1.8.3.1