mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-26 12:12:10 +01:00
Merge branch 'inline-macros' into 'main'
gmacros: Provide platform-independent G_ALWAYS_INLINE and G_NO_INLINE See merge request GNOME/glib!2781
This commit is contained in:
commit
8385f52db7
@ -516,6 +516,10 @@ G_CONST_RETURN
|
|||||||
G_NORETURN
|
G_NORETURN
|
||||||
G_NORETURN_FUNCPTR
|
G_NORETURN_FUNCPTR
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
G_ALWAYS_INLINE
|
||||||
|
G_NO_INLINE
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
G_N_ELEMENTS
|
G_N_ELEMENTS
|
||||||
</SECTION>
|
</SECTION>
|
||||||
@ -782,6 +786,7 @@ g_macro__has_attribute
|
|||||||
g_macro__has_builtin
|
g_macro__has_builtin
|
||||||
g_macro__has_feature
|
g_macro__has_feature
|
||||||
g_macro__has_extension
|
g_macro__has_extension
|
||||||
|
g_macro__has_attribute___always_inline__
|
||||||
g_macro__has_attribute___alloc_size__
|
g_macro__has_attribute___alloc_size__
|
||||||
g_macro__has_attribute___const__
|
g_macro__has_attribute___const__
|
||||||
g_macro__has_attribute___deprecated__
|
g_macro__has_attribute___deprecated__
|
||||||
|
110
glib/gmacros.h
110
glib/gmacros.h
@ -212,6 +212,9 @@
|
|||||||
* Declaring a function as `noinline` prevents the function from being
|
* Declaring a function as `noinline` prevents the function from being
|
||||||
* considered for inlining.
|
* considered for inlining.
|
||||||
*
|
*
|
||||||
|
* This macro is provided for retro-compatibility and will be eventually
|
||||||
|
* deprecated, but %G_NO_INLINE should be used instead.
|
||||||
|
*
|
||||||
* The attribute may be placed before the declaration or definition,
|
* The attribute may be placed before the declaration or definition,
|
||||||
* right before the `static` keyword.
|
* right before the `static` keyword.
|
||||||
*
|
*
|
||||||
@ -228,13 +231,10 @@
|
|||||||
* [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute)
|
* [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute)
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
|
* See also: %G_NO_INLINE, %G_ALWAYS_INLINE.
|
||||||
|
*
|
||||||
* Since: 2.58
|
* Since: 2.58
|
||||||
*/
|
*/
|
||||||
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_58 because it’s
|
|
||||||
* used within the GLib headers in function declarations which are always
|
|
||||||
* evaluated when a header is included. This results in warnings in third party
|
|
||||||
* code which includes glib.h, even if the third party code doesn’t use the new
|
|
||||||
* macro itself. */
|
|
||||||
|
|
||||||
#if g_macro__has_attribute(__pure__)
|
#if g_macro__has_attribute(__pure__)
|
||||||
#define G_GNUC_PURE __attribute__((__pure__))
|
#define G_GNUC_PURE __attribute__((__pure__))
|
||||||
@ -249,9 +249,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if g_macro__has_attribute(__noinline__)
|
#if g_macro__has_attribute(__noinline__)
|
||||||
#define G_GNUC_NO_INLINE __attribute__ ((__noinline__))
|
#define G_GNUC_NO_INLINE __attribute__ ((__noinline__)) \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_58
|
||||||
#else
|
#else
|
||||||
#define G_GNUC_NO_INLINE
|
#define G_GNUC_NO_INLINE \
|
||||||
|
GLIB_AVAILABLE_MACRO_IN_2_58
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1069,6 +1071,100 @@
|
|||||||
GLIB_AVAILABLE_MACRO_IN_2_68
|
GLIB_AVAILABLE_MACRO_IN_2_68
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_ALWAYS_INLINE:
|
||||||
|
*
|
||||||
|
* Expands to the GNU C `always_inline` or MSVC `__forceinline` function
|
||||||
|
* attribute depending on the compiler. It is used for declaring functions
|
||||||
|
* as always inlined, ignoring the compiler optimization levels.
|
||||||
|
*
|
||||||
|
* The attribute may be placed before the declaration or definition,
|
||||||
|
* right before the `static` keyword.
|
||||||
|
*
|
||||||
|
* |[<!-- language="C" -->
|
||||||
|
* G_ALWAYS_INLINE
|
||||||
|
* static int
|
||||||
|
* do_inline_this (void)
|
||||||
|
* {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* See the
|
||||||
|
* [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute)
|
||||||
|
* and the
|
||||||
|
* [MSVC documentation](https://docs.microsoft.com/en-us/visualstudio/misc/inline-inline-forceinline)
|
||||||
|
*
|
||||||
|
* Since: 2.74
|
||||||
|
*/
|
||||||
|
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_74 because it’s
|
||||||
|
* used within the GLib headers in function declarations which are always
|
||||||
|
* evaluated when a header is included. This results in warnings in third party
|
||||||
|
* code which includes glib.h, even if the third party code doesn’t use the new
|
||||||
|
* macro itself. */
|
||||||
|
#if g_macro__has_attribute(__always_inline__)
|
||||||
|
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||||
|
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||||
|
# define G_ALWAYS_INLINE [[gnu::always_inline]]
|
||||||
|
# else
|
||||||
|
# define G_ALWAYS_INLINE __attribute__ ((__always_inline__))
|
||||||
|
# endif
|
||||||
|
#elif defined (_MSC_VER)
|
||||||
|
/* Use MSVC specific syntax. */
|
||||||
|
# define G_ALWAYS_INLINE __forceinline
|
||||||
|
#else
|
||||||
|
# define G_ALWAYS_INLINE /* empty */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_NO_INLINE:
|
||||||
|
*
|
||||||
|
* Expands to the GNU C or MSVC `noinline` function attribute
|
||||||
|
* depending on the compiler. It is used for declaring functions
|
||||||
|
* preventing from being considered for inlining.
|
||||||
|
*
|
||||||
|
* Note that %G_NO_INLINE supersedes the previous %G_GNUC_NO_INLINE
|
||||||
|
* macro, which will eventually be deprecated.
|
||||||
|
* %G_NO_INLINE supports more platforms.
|
||||||
|
*
|
||||||
|
* The attribute may be placed before the declaration or definition,
|
||||||
|
* right before the `static` keyword.
|
||||||
|
*
|
||||||
|
* |[<!-- language="C" -->
|
||||||
|
* G_NO_INLINE
|
||||||
|
* static int
|
||||||
|
* do_not_inline_this (void)
|
||||||
|
* {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* Since: 2.74
|
||||||
|
*/
|
||||||
|
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_74 because it’s
|
||||||
|
* used within the GLib headers in function declarations which are always
|
||||||
|
* evaluated when a header is included. This results in warnings in third party
|
||||||
|
* code which includes glib.h, even if the third party code doesn’t use the new
|
||||||
|
* macro itself. */
|
||||||
|
#if g_macro__has_attribute(__noinline__)
|
||||||
|
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||||
|
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||||
|
# define G_NO_INLINE [[gnu::noinline]]
|
||||||
|
# else
|
||||||
|
# define G_NO_INLINE __attribute__ ((__noinline__))
|
||||||
|
# endif
|
||||||
|
#elif defined (_MSC_VER) && (1200 <= _MSC_VER)
|
||||||
|
/* Use MSVC specific syntax. */
|
||||||
|
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||||
|
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||||
|
# define G_NO_INLINE [[msvc::noinline]]
|
||||||
|
# else
|
||||||
|
# define G_NO_INLINE __declspec (noinline)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define G_NO_INLINE /* empty */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The G_LIKELY and G_UNLIKELY macros let the programmer give hints to
|
* The G_LIKELY and G_UNLIKELY macros let the programmer give hints to
|
||||||
* the compiler about the expected result of an expression. Some compilers
|
* the compiler about the expected result of an expression. Some compilers
|
||||||
|
@ -1490,7 +1490,8 @@ g_mutex_clear (GMutex *mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((noinline))
|
G_GNUC_NO_INLINE
|
||||||
|
static void
|
||||||
g_mutex_lock_slowpath (GMutex *mutex)
|
g_mutex_lock_slowpath (GMutex *mutex)
|
||||||
{
|
{
|
||||||
/* Set to contended. If it was empty before then we
|
/* Set to contended. If it was empty before then we
|
||||||
@ -1505,7 +1506,8 @@ g_mutex_lock_slowpath (GMutex *mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((noinline))
|
G_GNUC_NO_INLINE
|
||||||
|
static void
|
||||||
g_mutex_unlock_slowpath (GMutex *mutex,
|
g_mutex_unlock_slowpath (GMutex *mutex,
|
||||||
guint prev)
|
guint prev)
|
||||||
{
|
{
|
||||||
|
@ -160,6 +160,30 @@ test_atomic_int_exchange (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_NO_INLINE
|
||||||
|
static gboolean
|
||||||
|
do_not_inline_this (void)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_ALWAYS_INLINE
|
||||||
|
static inline gboolean
|
||||||
|
do_inline_this (void)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_inline_no_inline_macros (void)
|
||||||
|
{
|
||||||
|
g_test_message ("Test that G_NO_INLINE and G_ALWAYS_INLINE functions "
|
||||||
|
"can be compiled with C++ compiler");
|
||||||
|
|
||||||
|
g_assert_false (do_not_inline_this ());
|
||||||
|
g_assert_true (do_inline_this ());
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -176,6 +200,7 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/C++/atomic-int-compare-and-exchange-full", test_atomic_int_compare_and_exchange_full);
|
g_test_add_func ("/C++/atomic-int-compare-and-exchange-full", test_atomic_int_compare_and_exchange_full);
|
||||||
g_test_add_func ("/C++/atomic-pointer-exchange", test_atomic_pointer_exchange);
|
g_test_add_func ("/C++/atomic-pointer-exchange", test_atomic_pointer_exchange);
|
||||||
g_test_add_func ("/C++/atomic-int-exchange", test_atomic_int_exchange);
|
g_test_add_func ("/C++/atomic-int-exchange", test_atomic_int_exchange);
|
||||||
|
g_test_add_func ("/C++/inlined-not-inlined-functions", test_inline_no_inline_macros);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
@ -2160,7 +2160,7 @@ type_name##_get_type (void) \
|
|||||||
return static_g_define_type_id; \
|
return static_g_define_type_id; \
|
||||||
} /* closes type_name##_get_type() */ \
|
} /* closes type_name##_get_type() */ \
|
||||||
\
|
\
|
||||||
G_GNUC_NO_INLINE \
|
G_NO_INLINE \
|
||||||
static GType \
|
static GType \
|
||||||
type_name##_get_type_once (void) \
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
@ -2329,7 +2329,7 @@ type_name##_get_type (void) \
|
|||||||
return static_g_define_type_id; \
|
return static_g_define_type_id; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
G_GNUC_NO_INLINE \
|
G_NO_INLINE \
|
||||||
static GType \
|
static GType \
|
||||||
type_name##_get_type_once (void) \
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
@ -2366,7 +2366,7 @@ type_name##_get_type (void) \
|
|||||||
return static_g_define_type_id; \
|
return static_g_define_type_id; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
G_GNUC_NO_INLINE \
|
G_NO_INLINE \
|
||||||
static GType \
|
static GType \
|
||||||
type_name##_get_type_once (void) \
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
@ -2419,7 +2419,7 @@ type_name##_get_type (void) \
|
|||||||
return static_g_define_type_id; \
|
return static_g_define_type_id; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
G_GNUC_NO_INLINE \
|
G_NO_INLINE \
|
||||||
static GType \
|
static GType \
|
||||||
type_name##_get_type_once (void) \
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user