mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 19:10:09 +01:00
libnm: optimize NM_CONNECTION_GET_PRIVATE() for NMSimpleConnection
NMConnection is a glib interface, implemented only by NMSimpleConnection
and NMRemoteConnection.
Inside the daemon, every NMConnection instance is always a NMSimpleConnection.
Using glib interfaces has an overhead, for example NM_IS_CONNECTION() needs
to search the implemented types for the pointer. And NM_CONNECTION_GET_PRIVATE()
is implemented by attaching user data to the GObject instance. Both have measurable
overhead.
Special case them for NMSimpleConnection.
This optimizes primarily the call to nm_connection_get_setting_connection(),
which easily gets called millions of times. This is easily measurable.
(cherry picked from commit 7a71aedf46)
This commit is contained in:
parent
1c6b50f6ea
commit
5ccbe04788
3 changed files with 133 additions and 50 deletions
|
|
@ -46,19 +46,98 @@ enum {
|
|||
|
||||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
||||
typedef struct {
|
||||
NMConnection *self;
|
||||
|
||||
NMSetting *settings[_NM_META_SETTING_TYPE_NUM];
|
||||
|
||||
/* D-Bus path of the connection, if any */
|
||||
char *path;
|
||||
} NMConnectionPrivate;
|
||||
|
||||
G_DEFINE_INTERFACE(NMConnection, nm_connection, G_TYPE_OBJECT)
|
||||
|
||||
static NMConnectionPrivate *nm_connection_get_private(NMConnection *connection);
|
||||
#define NM_CONNECTION_GET_PRIVATE(o) (nm_connection_get_private((NMConnection *) o))
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean _nm_connection_clear_settings(NMConnection *connection, NMConnectionPrivate *priv);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#undef NM_IS_SIMPLE_CONNECTION
|
||||
#define NM_IS_SIMPLE_CONNECTION(self) \
|
||||
({ \
|
||||
gconstpointer _self1 = (self); \
|
||||
gboolean _result; \
|
||||
\
|
||||
_result = \
|
||||
(_self1 \
|
||||
&& (((GTypeInstance *) _self1)->g_class == _nm_simple_connection_class_instance)); \
|
||||
\
|
||||
nm_assert(_result == G_TYPE_CHECK_INSTANCE_TYPE(_self1, NM_TYPE_SIMPLE_CONNECTION)); \
|
||||
\
|
||||
_result; \
|
||||
})
|
||||
|
||||
#undef NM_IS_CONNECTION
|
||||
#define NM_IS_CONNECTION(self) \
|
||||
({ \
|
||||
gconstpointer _self0 = (self); \
|
||||
\
|
||||
(_self0 \
|
||||
&& (NM_IS_SIMPLE_CONNECTION(_self0) \
|
||||
|| G_TYPE_CHECK_INSTANCE_TYPE(_self0, NM_TYPE_CONNECTION))); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
_nm_connection_private_clear(NMConnectionPrivate *priv)
|
||||
{
|
||||
if (priv->self) {
|
||||
_nm_connection_clear_settings(priv->self, priv);
|
||||
nm_clear_g_free(&priv->path);
|
||||
priv->self = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_nm_connection_private_free(gpointer data)
|
||||
{
|
||||
NMConnectionPrivate *priv = data;
|
||||
|
||||
_nm_connection_private_clear(priv);
|
||||
|
||||
nm_g_slice_free(priv);
|
||||
}
|
||||
|
||||
static NMConnectionPrivate *
|
||||
_nm_connection_get_private_from_qdata(NMConnection *connection)
|
||||
{
|
||||
GQuark key;
|
||||
NMConnectionPrivate *priv;
|
||||
|
||||
nm_assert(NM_IS_CONNECTION(connection));
|
||||
nm_assert(!NM_IS_SIMPLE_CONNECTION(connection));
|
||||
|
||||
key = NM_CACHED_QUARK("NMConnectionPrivate");
|
||||
|
||||
priv = g_object_get_qdata((GObject *) connection, key);
|
||||
if (G_UNLIKELY(!priv)) {
|
||||
priv = g_slice_new(NMConnectionPrivate);
|
||||
*priv = (NMConnectionPrivate){
|
||||
.self = connection,
|
||||
};
|
||||
g_object_set_qdata_full((GObject *) connection, key, priv, _nm_connection_private_free);
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
#define NM_CONNECTION_GET_PRIVATE(connection) \
|
||||
({ \
|
||||
NMConnection * _connection = (connection); \
|
||||
NMConnectionPrivate *_priv; \
|
||||
\
|
||||
if (G_LIKELY(NM_IS_SIMPLE_CONNECTION(_connection))) \
|
||||
_priv = (gpointer) (&(((char *) _connection)[_nm_simple_connection_private_offset])); \
|
||||
else \
|
||||
_priv = _nm_connection_get_private_from_qdata(_connection); \
|
||||
\
|
||||
nm_assert(_priv && _priv->self == _connection); \
|
||||
\
|
||||
_priv; \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -3557,41 +3636,6 @@ _nm_connection_get_setting_bluetooth_for_nap(NMConnection *connection)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_connection_private_free(NMConnectionPrivate *priv)
|
||||
{
|
||||
NMConnection *self = priv->self;
|
||||
|
||||
_nm_connection_clear_settings(self, priv);
|
||||
g_free(priv->path);
|
||||
|
||||
g_slice_free(NMConnectionPrivate, priv);
|
||||
}
|
||||
|
||||
static NMConnectionPrivate *
|
||||
nm_connection_get_private(NMConnection *connection)
|
||||
{
|
||||
GQuark key;
|
||||
NMConnectionPrivate *priv;
|
||||
|
||||
nm_assert(NM_IS_CONNECTION(connection));
|
||||
|
||||
key = NM_CACHED_QUARK("NMConnectionPrivate");
|
||||
|
||||
priv = g_object_get_qdata((GObject *) connection, key);
|
||||
if (G_UNLIKELY(!priv)) {
|
||||
priv = g_slice_new0(NMConnectionPrivate);
|
||||
g_object_set_qdata_full((GObject *) connection,
|
||||
key,
|
||||
priv,
|
||||
(GDestroyNotify) nm_connection_private_free);
|
||||
|
||||
priv->self = connection;
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_connection_default_init(NMConnectionInterface *iface)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,6 +19,22 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMConnection *self;
|
||||
|
||||
NMSetting *settings[_NM_META_SETTING_TYPE_NUM];
|
||||
|
||||
/* D-Bus path of the connection, if any */
|
||||
char *path;
|
||||
} NMConnectionPrivate;
|
||||
|
||||
extern GTypeClass *_nm_simple_connection_class_instance;
|
||||
extern int _nm_simple_connection_private_offset;
|
||||
|
||||
void _nm_connection_private_clear(NMConnectionPrivate *priv);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* NMSetting:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
GTypeClass *_nm_simple_connection_class_instance = NULL;
|
||||
int _nm_simple_connection_private_offset;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* NMSimpleConnection:
|
||||
*/
|
||||
|
|
@ -42,11 +47,20 @@ G_DEFINE_TYPE_WITH_CODE(NMSimpleConnection,
|
|||
G_IMPLEMENT_INTERFACE(NM_TYPE_CONNECTION,
|
||||
nm_simple_connection_interface_init);)
|
||||
|
||||
#define _GET_PRIVATE(self) \
|
||||
G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_SIMPLE_CONNECTION, NMConnectionPrivate)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_simple_connection_init(NMSimpleConnection *self)
|
||||
{}
|
||||
{
|
||||
NMConnectionPrivate *priv;
|
||||
|
||||
priv = _GET_PRIVATE(self);
|
||||
|
||||
priv->self = (NMConnection *) self;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_simple_connection_new:
|
||||
|
|
@ -143,22 +157,31 @@ nm_simple_connection_new_clone(NMConnection *connection)
|
|||
static void
|
||||
dispose(GObject *object)
|
||||
{
|
||||
NMConnection *connection = NM_CONNECTION(object);
|
||||
|
||||
#if NM_MORE_ASSERTS
|
||||
g_signal_handlers_disconnect_by_data(object,
|
||||
(gpointer) &_nmtst_connection_unchanging_user_data);
|
||||
#endif
|
||||
|
||||
nm_connection_clear_secrets(NM_CONNECTION(object));
|
||||
nm_connection_clear_secrets(connection);
|
||||
|
||||
_nm_connection_private_clear(_GET_PRIVATE(connection));
|
||||
|
||||
G_OBJECT_CLASS(nm_simple_connection_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_simple_connection_class_init(NMSimpleConnectionClass *simple_class)
|
||||
nm_simple_connection_class_init(NMSimpleConnectionClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(simple_class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof(NMConnectionPrivate));
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
_nm_simple_connection_private_offset = g_type_class_get_instance_private_offset(klass);
|
||||
_nm_simple_connection_class_instance = (GTypeClass *) klass;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue