Remove Wakeups API

The API relied on /proc/timer_stats which has been removed from the
kernel in 2017. Since then, the API has been non-functional (yet
incorrectly reporting support because the support test was buggy).

Just remove it completely. The debian codesearch does not uncover any
API users. Also, I doubt that any new API (based on tracing scheduler
events as perf would do) would map well to what exists now. i.e. if
something like this is re-implemented in UPower or elsewhere, then the
API should likely look different.

And, realistically, if this does need root privileges (i.e. can't be
moved to use BPF programs or so on user units), then we can also create
a new small daemon that is launched on-demand just for that.
This commit is contained in:
Benjamin Berg 2022-03-24 16:08:16 +01:00
parent 1003d5c2a6
commit 9058d45685
18 changed files with 0 additions and 1924 deletions

View file

@ -3,7 +3,6 @@ upowerd_dbus_interfaces = [
[ 'daemon', 'org.freedesktop.UPower', 'Daemon' ],
[ 'device', 'org.freedesktop.UPower.Device', 'Device' ],
[ 'kbd-backlight', 'org.freedesktop.UPower.KbdBacklight', 'KbdBacklight' ],
[ 'wakeups', 'org.freedesktop.UPower.Wakeups', 'Wakeups' ],
]
upowerd_dbus_headers = []

View file

@ -1,131 +0,0 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" [
<!ENTITY ERROR_GENERAL "org.freedesktop.UPower.GeneralError">
]>
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.UPower.Wakeups">
<doc:doc>
<doc:description>
<doc:para>
org.freedesktop.UPower.Wakeups is a DBus interface implemented
by UPower.
It allows applications to watch what applications and drivers are
causing the wakeups on the system.
</doc:para>
</doc:description>
</doc:doc>
<property name="HasCapability" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
If the system has the ability to profile wakeups.
</doc:para>
</doc:description>
</doc:doc>
</property>
<!-- ************************************************************ -->
<method name="GetTotal">
<arg name="value" direction="out" type="u">
<doc:doc>
<doc:summary>
The number of wakeups per second.
</doc:summary>
</doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Get the number of wakeups per second.
</doc:para>
</doc:description>
<doc:errors>
<doc:error name="&ERROR_GENERAL;">if an error occured while getting the latency</doc:error>
</doc:errors>
</doc:doc>
</method>
<!-- ************************************************************ -->
<signal name="TotalChanged">
<arg name="value" direction="out" type="u">
<doc:doc>
<doc:summary>
The number of wakeups per second.
</doc:summary>
</doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
The number of wakeups per second has changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<method name="GetData">
<arg name="data" direction="out" type="a(budss)">
<doc:doc>
<doc:summary>
The data of all the processes and drivers which contribute to the
wakeups on the system.
<doc:list>
<doc:item>
<doc:term>is_userspace</doc:term>
<doc:definition>
If the wakeup is from userspace.
</doc:definition>
</doc:item>
<doc:item>
<doc:term>id</doc:term>
<doc:definition>
The process ID of the application, or the IRQ for kernel drivers.
</doc:definition>
</doc:item>
<doc:item>
<doc:term>value</doc:term>
<doc:definition>
The number of wakeups per second.
</doc:definition>
</doc:item>
<doc:item>
<doc:term>cmdline</doc:term>
<doc:definition>
The command line for the application, or NULL for kernel drivers.
</doc:definition>
</doc:item>
<doc:item>
<doc:term>details</doc:term>
<doc:definition>
The details about the wakeup.
</doc:definition>
</doc:item>
</doc:list>
</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Gets all the wakeups from drivers and applications.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<signal name="DataChanged">
<doc:doc>
<doc:description>
<doc:para>
The wakeup data has changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
</interface>
</node>

View file

@ -25,7 +25,6 @@
<arg><option>--monitor</option></arg>
<arg><option>--show-info</option></arg>
<arg><option>--version</option></arg>
<arg><option>--wakeups</option></arg>
<arg><option>--help</option></arg>
</cmdsynopsis>
</refsynopsisdiv>

View file

@ -80,7 +80,6 @@
<xi:include href="xml/up-device.xml"/>
<xi:include href="xml/up-history-item.xml"/>
<xi:include href="xml/up-stats-item.xml"/>
<xi:include href="xml/up-wakeup-item.xml"/>
</reference>
<reference id="libupower-glib-helpers">

View file

@ -19,10 +19,8 @@ libupower_glib_headers = [
'up-autocleanups.h',
'up-types.h',
'up-device.h',
'up-wakeup-item.h',
'up-stats-item.h',
'up-history-item.h',
'up-wakeups.h',
'up-client.h',
up_version_h,
]
@ -30,8 +28,6 @@ libupower_glib_headers = [
libupower_glib_sources = [
'up-types.c',
'up-client.c',
'up-wakeups.c',
'up-wakeup-item.c',
'up-stats-item.c',
'up-history-item.c',
'up-device.c',

View file

@ -32,8 +32,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpClient, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpDevice, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpHistoryItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpStatsItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpWakeupItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpWakeups, g_object_unref)
#endif

View file

@ -1,452 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2008-2010 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* SECTION:up-wakeup-item
* @short_description: Helper object representing one item of wakeup data.
* @see_also: #UpDevice, #UpClient
*
* This object represents one item of data which may be returned from the
* daemon in response to a query.
*/
#include "config.h"
#include <glib.h>
#include "up-wakeup-item.h"
static void up_wakeup_item_class_init (UpWakeupItemClass *klass);
static void up_wakeup_item_init (UpWakeupItem *wakeup_item);
static void up_wakeup_item_finalize (GObject *object);
struct UpWakeupItemPrivate
{
gboolean is_userspace;
guint id;
guint old;
gdouble value;
gchar *cmdline;
gchar *details;
};
enum {
PROP_0,
PROP_IS_USERSPACE,
PROP_ID,
PROP_OLD,
PROP_VALUE,
PROP_CMDLINE,
PROP_DETAILS,
PROP_LAST
};
G_DEFINE_TYPE_WITH_PRIVATE (UpWakeupItem, up_wakeup_item, G_TYPE_OBJECT)
/**
* up_wakeup_item_get_is_userspace:
* @wakeup_item: #UpWakeupItem
*
* Gets if the item is userspace.
*
* Return value: the value
*
* Since: 0.9.0
**/
gboolean
up_wakeup_item_get_is_userspace (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), FALSE);
return wakeup_item->priv->is_userspace;
}
/**
* up_wakeup_item_set_is_userspace:
* @wakeup_item: #UpWakeupItem
* @is_userspace: the new value
*
* Sets if the item is userspace.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_is_userspace (UpWakeupItem *wakeup_item, gboolean is_userspace)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
wakeup_item->priv->is_userspace = is_userspace;
g_object_notify (G_OBJECT(wakeup_item), "is-userspace");
}
/**
* up_wakeup_item_get_id:
* @wakeup_item: #UpWakeupItem
*
* Gets the item id.
*
* Return value: the value
*
* Since: 0.9.0
**/
guint
up_wakeup_item_get_id (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), G_MAXUINT);
return wakeup_item->priv->id;
}
/**
* up_wakeup_item_set_id:
* @wakeup_item: #UpWakeupItem
* @id: the new value
*
* Sets the item id.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_id (UpWakeupItem *wakeup_item, guint id)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
wakeup_item->priv->id = id;
g_object_notify (G_OBJECT(wakeup_item), "id");
}
/**
* up_wakeup_item_get_old:
* @wakeup_item: #UpWakeupItem
*
* Gets the item old.
*
* Return value: the value
*
* Since: 0.9.0
**/
guint
up_wakeup_item_get_old (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), G_MAXUINT);
return wakeup_item->priv->old;
}
/**
* up_wakeup_item_set_old:
* @wakeup_item: #UpWakeupItem
* @old: the new value
*
* Sets the item old.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_old (UpWakeupItem *wakeup_item, guint old)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
wakeup_item->priv->old = old;
g_object_notify (G_OBJECT(wakeup_item), "old");
}
/**
* up_wakeup_item_get_value:
* @wakeup_item: #UpWakeupItem
*
* Gets the item value.
*
* Return value: the value
*
* Since: 0.9.0
**/
gdouble
up_wakeup_item_get_value (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), G_MAXDOUBLE);
return wakeup_item->priv->value;
}
/**
* up_wakeup_item_set_value:
* @wakeup_item: #UpWakeupItem
* @value: the new value
*
* Sets the item value.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_value (UpWakeupItem *wakeup_item, gdouble value)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
wakeup_item->priv->value = value;
g_object_notify (G_OBJECT(wakeup_item), "value");
}
/**
* up_wakeup_item_get_cmdline:
* @wakeup_item: #UpWakeupItem
*
* Gets the item cmdline.
*
* Return value: the value
*
* Since: 0.9.0
**/
const gchar *
up_wakeup_item_get_cmdline (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), NULL);
return wakeup_item->priv->cmdline;
}
/**
* up_wakeup_item_set_cmdline:
* @wakeup_item: #UpWakeupItem
* @cmdline: the new value
*
* Sets the item cmdline.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_cmdline (UpWakeupItem *wakeup_item, const gchar *cmdline)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
g_free (wakeup_item->priv->cmdline);
wakeup_item->priv->cmdline = g_strdup (cmdline);
g_object_notify (G_OBJECT(wakeup_item), "cmdline");
}
/**
* up_wakeup_item_get_details:
* @wakeup_item: #UpWakeupItem
*
* Gets the item details.
*
* Return value: the value
*
* Since: 0.9.0
**/
const gchar *
up_wakeup_item_get_details (UpWakeupItem *wakeup_item)
{
g_return_val_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item), NULL);
return wakeup_item->priv->details;
}
/**
* up_wakeup_item_set_details:
* @wakeup_item: #UpWakeupItem
* @details: the new value
*
* Sets the item details.
*
* Since: 0.9.0
**/
void
up_wakeup_item_set_details (UpWakeupItem *wakeup_item, const gchar *details)
{
g_return_if_fail (UP_IS_WAKEUP_ITEM (wakeup_item));
g_free (wakeup_item->priv->details);
wakeup_item->priv->details = g_strdup (details);
g_object_notify (G_OBJECT(wakeup_item), "details");
}
/**
* up_wakeup_item_set_property:
**/
static void
up_wakeup_item_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
UpWakeupItem *wakeup_item = UP_WAKEUP_ITEM (object);
switch (prop_id) {
case PROP_IS_USERSPACE:
wakeup_item->priv->is_userspace = g_value_get_boolean (value);
break;
case PROP_ID:
wakeup_item->priv->id = g_value_get_uint (value);
break;
case PROP_OLD:
wakeup_item->priv->old = g_value_get_uint (value);
break;
case PROP_VALUE:
wakeup_item->priv->value = g_value_get_double (value);
break;
case PROP_CMDLINE:
g_free (wakeup_item->priv->cmdline);
wakeup_item->priv->cmdline = g_strdup (g_value_get_string (value));
break;
case PROP_DETAILS:
g_free (wakeup_item->priv->details);
wakeup_item->priv->details = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* up_wakeup_item_get_property:
**/
static void
up_wakeup_item_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
UpWakeupItem *wakeup_item = UP_WAKEUP_ITEM (object);
switch (prop_id) {
case PROP_IS_USERSPACE:
g_value_set_boolean (value, wakeup_item->priv->is_userspace);
break;
case PROP_ID:
g_value_set_uint (value, wakeup_item->priv->id);
break;
case PROP_OLD:
g_value_set_uint (value, wakeup_item->priv->old);
break;
case PROP_VALUE:
g_value_set_double (value, wakeup_item->priv->value);
break;
case PROP_CMDLINE:
g_value_set_string (value, wakeup_item->priv->cmdline);
break;
case PROP_DETAILS:
g_value_set_string (value, wakeup_item->priv->details);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* up_wakeup_item_class_init:
* @klass: The UpWakeupItemClass
**/
static void
up_wakeup_item_class_init (UpWakeupItemClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = up_wakeup_item_finalize;
object_class->set_property = up_wakeup_item_set_property;
object_class->get_property = up_wakeup_item_get_property;
/**
* UpWakeupItem:is-userspace:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_IS_USERSPACE,
g_param_spec_boolean ("is-userspace", NULL, NULL,
FALSE,
G_PARAM_READWRITE));
/**
* UpWakeupItem:id:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_ID,
g_param_spec_uint ("id", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
/**
* UpWakeupItem:old:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_OLD,
g_param_spec_uint ("old", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
/**
* UpWakeupItem:value:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_VALUE,
g_param_spec_double ("value", NULL, NULL,
0.0, G_MAXDOUBLE, 0.0,
G_PARAM_READWRITE));
/**
* UpWakeupItem:cmdline:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_CMDLINE,
g_param_spec_string ("cmdline", NULL, NULL,
NULL,
G_PARAM_READWRITE));
/**
* UpWakeupItem:details:
*
* Since: 0.9.0
**/
g_object_class_install_property (object_class,
PROP_DETAILS,
g_param_spec_string ("details", NULL, NULL,
NULL,
G_PARAM_READWRITE));
}
/**
* up_wakeup_item_init:
* @wakeup_item: This class instance
**/
static void
up_wakeup_item_init (UpWakeupItem *wakeup_item)
{
wakeup_item->priv = up_wakeup_item_get_instance_private (wakeup_item);
}
/**
* up_wakeup_item_finalize:
* @object: The object to finalize
**/
static void
up_wakeup_item_finalize (GObject *object)
{
UpWakeupItem *wakeup_item;
g_return_if_fail (UP_IS_WAKEUP_ITEM (object));
wakeup_item = UP_WAKEUP_ITEM (object);
g_free (wakeup_item->priv->cmdline);
g_free (wakeup_item->priv->details);
G_OBJECT_CLASS (up_wakeup_item_parent_class)->finalize (object);
}
/**
* up_wakeup_item_new:
*
* Return value: a new UpWakeupItem object.
*
* Since: 0.9.0
**/
UpWakeupItem *
up_wakeup_item_new (void)
{
return UP_WAKEUP_ITEM (g_object_new (UP_TYPE_WAKEUP_ITEM, NULL));
}

View file

@ -1,78 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined (__UPOWER_H_INSIDE__) && !defined (UP_COMPILATION)
#error "Only <upower.h> can be included directly."
#endif
#ifndef __UP_WAKEUP_ITEM_H
#define __UP_WAKEUP_ITEM_H
#include <glib-object.h>
#include <libupower-glib/up-types.h>
G_BEGIN_DECLS
#define UP_TYPE_WAKEUP_ITEM (up_wakeup_item_get_type ())
#define UP_WAKEUP_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UP_TYPE_WAKEUP_ITEM, UpWakeupItem))
#define UP_WAKEUP_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), UP_TYPE_WAKEUP_ITEM, UpWakeupItemClass))
#define UP_IS_WAKEUP_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UP_TYPE_WAKEUP_ITEM))
#define UP_IS_WAKEUP_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), UP_TYPE_WAKEUP_ITEM))
#define UP_WAKEUP_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), UP_TYPE_WAKEUP_ITEM, UpWakeupItemClass))
typedef struct UpWakeupItemPrivate UpWakeupItemPrivate;
typedef struct {
GObject parent;
UpWakeupItemPrivate *priv;
} UpWakeupItem;
typedef struct {
GObjectClass parent_class;
} UpWakeupItemClass;
GType up_wakeup_item_get_type (void);
UpWakeupItem *up_wakeup_item_new (void);
/* accessors */
gboolean up_wakeup_item_get_is_userspace (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_is_userspace (UpWakeupItem *wakeup_item,
gboolean is_userspace);
guint up_wakeup_item_get_id (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_id (UpWakeupItem *wakeup_item,
guint id);
guint up_wakeup_item_get_old (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_old (UpWakeupItem *wakeup_item,
guint old);
gdouble up_wakeup_item_get_value (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_value (UpWakeupItem *wakeup_item,
gdouble value);
const gchar *up_wakeup_item_get_cmdline (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_cmdline (UpWakeupItem *wakeup_item,
const gchar *cmdline);
const gchar *up_wakeup_item_get_details (UpWakeupItem *wakeup_item);
void up_wakeup_item_set_details (UpWakeupItem *wakeup_item,
const gchar *details);
G_END_DECLS
#endif /* __UP_WAKEUP_ITEM_H */

View file

@ -1,296 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <glib-object.h>
#include "up-wakeups.h"
#include "up-wakeups-generated.h"
static void up_wakeups_class_init (UpWakeupsClass *klass);
static void up_wakeups_init (UpWakeups *wakeups);
static void up_wakeups_finalize (GObject *object);
struct UpWakeupsPrivate
{
UpExportedWakeups *proxy;
};
enum {
UP_WAKEUPS_DATA_CHANGED,
UP_WAKEUPS_TOTAL_CHANGED,
UP_WAKEUPS_LAST_SIGNAL
};
static guint signals [UP_WAKEUPS_LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_PRIVATE (UpWakeups, up_wakeups, G_TYPE_OBJECT)
/**
* up_wakeups_get_total_sync:
* @wakeups: a #UpWakeups instance.
* @cancellable: a #GCancellable or %NULL
* @error: a #GError, or %NULL.
*
* Gets the the total number of wakeups per second from the daemon.
*
* Return value: number of wakeups per second.
*
* Since: 0.9.1
**/
guint
up_wakeups_get_total_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
{
guint total = 0;
gboolean ret;
g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
g_return_val_if_fail (wakeups->priv->proxy != NULL, FALSE);
ret = up_exported_wakeups_call_get_total_sync (wakeups->priv->proxy, &total,
cancellable, error);
if (!ret)
total = 0;
return total;
}
/**
* up_wakeups_get_data_sync:
* @wakeups: a #UpWakeups instance.
* @cancellable: a #GCancellable or %NULL
* @error: a #GError, or %NULL.
*
* Gets the wakeups data from the daemon.
*
* Return value: (element-type UpWakeupItem) (transfer full): an array of %UpWakeupItem's
*
* Since: 0.9.1
**/
GPtrArray *
up_wakeups_get_data_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
{
GError *error_local = NULL;
GVariant *gva;
guint i;
GPtrArray *array = NULL;
gboolean ret;
gsize len;
GVariantIter *iter;
g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), NULL);
g_return_val_if_fail (wakeups->priv->proxy != NULL, NULL);
/* get compound data */
ret = up_exported_wakeups_call_get_data_sync (wakeups->priv->proxy,
&gva,
NULL,
&error_local);
if (!ret) {
g_warning ("GetData on failed: %s", error_local->message);
g_set_error (error, 1, 0, "%s", error_local->message);
g_error_free (error_local);
goto out;
}
/* no data */
iter = g_variant_iter_new (gva);
len = g_variant_iter_n_children (iter);
if (len == 0) {
g_variant_iter_free (iter);
goto out;
}
/* convert */
array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
for (i = 0; i < len; i++) {
UpWakeupItem *obj;
GVariant *v;
gboolean is_userspace;
guint32 id;
double value;
char *cmdline;
char *details;
v = g_variant_iter_next_value (iter);
g_variant_get (v, "(budss)",
&is_userspace, &id, &value, &cmdline, &details);
g_variant_unref (v);
obj = up_wakeup_item_new ();
up_wakeup_item_set_is_userspace (obj, is_userspace);
up_wakeup_item_set_id (obj, id);
up_wakeup_item_set_value (obj, value);
up_wakeup_item_set_cmdline (obj, cmdline);
up_wakeup_item_set_details (obj, details);
g_free (cmdline);
g_free (details);
g_ptr_array_add (array, obj);
}
g_variant_iter_free (iter);
out:
g_clear_pointer (&gva, g_variant_unref);
return array;
}
/**
* up_wakeups_get_properties_sync:
* @wakeups: a #UpWakeups instance.
* @cancellable: a #GCancellable or %NULL
* @error: a #GError, or %NULL.
*
* Gets properties from the daemon about wakeup data.
*
* Return value: %TRUE if supported
*
* Since: 0.9.1
**/
gboolean
up_wakeups_get_properties_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
{
g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
/* Nothing to do here */
return TRUE;
}
/**
* up_wakeups_get_has_capability:
* @wakeups: a #UpWakeups instance.
*
* Returns if the daemon supports getting the wakeup data.
*
* Return value: %TRUE if supported
*
* Since: 0.9.1
**/
gboolean
up_wakeups_get_has_capability (UpWakeups *wakeups)
{
g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
return up_exported_wakeups_get_has_capability (wakeups->priv->proxy);
}
/**
* up_wakeups_total_changed_cb:
**/
static void
up_wakeups_total_changed_cb (UpExportedWakeups *proxy, guint value, UpWakeups *wakeups)
{
g_signal_emit (wakeups, signals [UP_WAKEUPS_TOTAL_CHANGED], 0, value);
}
/**
* up_wakeups_data_changed_cb:
**/
static void
up_wakeups_data_changed_cb (UpExportedWakeups *proxy, UpWakeups *wakeups)
{
g_signal_emit (wakeups, signals [UP_WAKEUPS_DATA_CHANGED], 0);
}
/**
* up_wakeups_class_init:
**/
static void
up_wakeups_class_init (UpWakeupsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = up_wakeups_finalize;
signals [UP_WAKEUPS_DATA_CHANGED] =
g_signal_new ("data-changed",
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UpWakeupsClass, data_changed),
NULL, NULL, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals [UP_WAKEUPS_TOTAL_CHANGED] =
g_signal_new ("total-changed",
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UpWakeupsClass, data_changed),
NULL, NULL, g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
}
/**
* up_wakeups_init:
**/
static void
up_wakeups_init (UpWakeups *wakeups)
{
GError *error = NULL;
wakeups->priv = up_wakeups_get_instance_private (wakeups);
/* connect to main interface */
wakeups->priv->proxy = up_exported_wakeups_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
"org.freedesktop.UPower",
"/org/freedesktop/UPower/Wakeups",
NULL,
&error);
if (wakeups->priv->proxy == NULL) {
g_warning ("Couldn't connect to proxy: %s", error->message);
g_error_free (error);
return;
}
/* all callbacks */
g_signal_connect (wakeups->priv->proxy, "total-changed",
G_CALLBACK (up_wakeups_total_changed_cb), wakeups);
g_signal_connect (wakeups->priv->proxy, "data-changed",
G_CALLBACK (up_wakeups_data_changed_cb), wakeups);
}
/**
* up_wakeups_finalize:
**/
static void
up_wakeups_finalize (GObject *object)
{
UpWakeups *wakeups;
g_return_if_fail (UP_IS_WAKEUPS (object));
wakeups = UP_WAKEUPS (object);
g_clear_object (&wakeups->priv->proxy);
G_OBJECT_CLASS (up_wakeups_parent_class)->finalize (object);
}
/**
* up_wakeups_new:
*
* Gets a new object to allow querying the wakeups data from the server.
*
* Return value: the a new @UpWakeups object.
*
* Since: 0.9.1
**/
UpWakeups *
up_wakeups_new (void)
{
return UP_WAKEUPS (g_object_new (UP_TYPE_WAKEUPS, NULL));
}

View file

@ -1,83 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined (__UPOWER_H_INSIDE__) && !defined (UP_COMPILATION)
#error "Only <upower.h> can be included directly."
#endif
#ifndef __UP_WAKEUPS_H
#define __UP_WAKEUPS_H
#include <glib-object.h>
#include <gio/gio.h>
#include <libupower-glib/up-types.h>
#include <libupower-glib/up-device.h>
#include <libupower-glib/up-wakeup-item.h>
G_BEGIN_DECLS
#define UP_TYPE_WAKEUPS (up_wakeups_get_type ())
#define UP_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UP_TYPE_WAKEUPS, UpWakeups))
#define UP_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), UP_TYPE_WAKEUPS, UpWakeupsClass))
#define UP_IS_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UP_TYPE_WAKEUPS))
#define UP_IS_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), UP_TYPE_WAKEUPS))
#define UP_WAKEUPS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), UP_TYPE_WAKEUPS, UpWakeupsClass))
#define UP_WAKEUPS_ERROR (up_wakeups_error_quark ())
#define UP_WAKEUPS_TYPE_ERROR (up_wakeups_error_get_type ())
typedef struct UpWakeupsPrivate UpWakeupsPrivate;
typedef struct
{
GObject parent;
UpWakeupsPrivate *priv;
} UpWakeups;
typedef struct
{
GObjectClass parent_class;
void (*data_changed) (UpWakeups *wakeups);
void (*total_changed) (UpWakeups *wakeups,
guint value);
} UpWakeupsClass;
GType up_wakeups_get_type (void);
UpWakeups *up_wakeups_new (void);
/* sync versions */
guint up_wakeups_get_total_sync (UpWakeups *wakeups,
GCancellable *cancellable,
GError **error);
GPtrArray *up_wakeups_get_data_sync (UpWakeups *wakeups,
GCancellable *cancellable,
GError **error);
gboolean up_wakeups_get_properties_sync (UpWakeups *wakeups,
GCancellable *cancellable,
GError **error);
/* accessors */
gboolean up_wakeups_get_has_capability (UpWakeups *wakeups);
G_END_DECLS
#endif /* __UP_WAKEUPS_H */

View file

@ -39,8 +39,6 @@
#include <libupower-glib/up-device.h>
#include <libupower-glib/up-history-item.h>
#include <libupower-glib/up-stats-item.h>
#include <libupower-glib/up-wakeup-item.h>
#include <libupower-glib/up-wakeups.h>
#include <libupower-glib/up-autocleanups.h>

View file

@ -35,8 +35,6 @@ upowerd_private = static_library('upowerd-private',
'up-device-list.c',
'up-kbd-backlight.h',
'up-kbd-backlight.c',
'up-wakeups.h',
'up-wakeups.c',
'up-history.h',
'up-history.c',
'up-backend.h',

View file

@ -21,8 +21,6 @@
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.freedesktop.UPower.KbdBacklight"
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.freedesktop.UPower.Wakeups"
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.freedesktop.UPower"
send_interface="org.freedesktop.UPower"/>
@ -30,7 +28,5 @@
send_interface="org.freedesktop.UPower.Device"/>
<allow send_destination="org.freedesktop.UPower"
send_interface="org.freedesktop.UPower.KbdBacklight"/>
<allow send_destination="org.freedesktop.UPower"
send_interface="org.freedesktop.UPower.Wakeups"/>
</policy>
</busconfig>

View file

@ -36,13 +36,11 @@
#include "up-daemon.h"
#include "up-kbd-backlight.h"
#include "up-wakeups.h"
#define DEVKIT_POWER_SERVICE_NAME "org.freedesktop.UPower"
typedef struct UpState {
UpKbdBacklight *kbd_backlight;
UpWakeups *wakeups;
UpDaemon *daemon;
GMainLoop *loop;
} UpState;
@ -53,7 +51,6 @@ up_state_free (UpState *state)
up_daemon_shutdown (state->daemon);
g_clear_object (&state->kbd_backlight);
g_clear_object (&state->wakeups);
g_clear_object (&state->daemon);
g_clear_pointer (&state->loop, g_main_loop_unref);
@ -66,7 +63,6 @@ up_state_new (void)
UpState *state = g_new0 (UpState, 1);
state->kbd_backlight = up_kbd_backlight_new ();
state->wakeups = up_wakeups_new ();
state->daemon = up_daemon_new ();
state->loop = g_main_loop_new (NULL, FALSE);
@ -84,7 +80,6 @@ up_main_bus_acquired (GDBusConnection *connection,
UpState *state = user_data;
up_kbd_backlight_register (state->kbd_backlight, connection);
up_wakeups_register (state->wakeups, connection);
if (!up_daemon_startup (state->daemon, connection)) {
g_warning ("Could not startup; bailing out");
g_main_loop_quit (state->loop);

View file

@ -33,7 +33,6 @@
#include "up-device-list.h"
#include "up-history.h"
#include "up-native.h"
#include "up-wakeups.h"
gchar *history_dir = NULL;
@ -275,18 +274,6 @@ up_test_history_func (void)
rmdir (history_dir);
}
static void
up_test_wakeups_func (void)
{
UpWakeups *wakeups;
wakeups = up_wakeups_new ();
g_assert (wakeups != NULL);
/* unref */
g_object_unref (wakeups);
}
int
main (int argc, char **argv)
{
@ -303,7 +290,6 @@ main (int argc, char **argv)
g_test_add_func ("/power/device_list", up_test_device_list_func);
g_test_add_func ("/power/history", up_test_history_func);
g_test_add_func ("/power/native", up_test_native_func);
g_test_add_func ("/power/wakeups", up_test_wakeups_func);
g_test_add_func ("/power/daemon", up_test_daemon_func);
return g_test_run ();

View file

@ -1,726 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "up-wakeups.h"
#include "up-daemon.h"
#include "up-wakeup-item.h"
static void up_wakeups_finalize (GObject *object);
static gboolean up_wakeups_timerstats_enable (UpWakeups *wakeups);
#define UP_WAKEUPS_POLL_INTERVAL_KERNEL 2 /* seconds */
#define UP_WAKEUPS_POLL_INTERVAL_USERSPACE 2 /* seconds */
#define UP_WAKEUPS_DISABLE_INTERVAL 30 /* seconds */
#define UP_WAKEUPS_SOURCE_KERNEL "/proc/interrupts"
#define UP_WAKEUPS_SOURCE_USERSPACE "/proc/timer_stats"
#define UP_WAKEUPS_SMALLEST_VALUE 0.1f /* seconds */
#define UP_WAKEUPS_TOTAL_SMOOTH_FACTOR 0.125f
struct UpWakeupsPrivate
{
GPtrArray *data;
guint total_old;
guint total_ave;
guint poll_userspace_id;
guint poll_kernel_id;
guint disable_id;
gboolean polling_enabled;
};
G_DEFINE_TYPE_WITH_PRIVATE (UpWakeups, up_wakeups, UP_TYPE_EXPORTED_WAKEUPS_SKELETON)
/**
* up_wakeups_get_cmdline:
**/
static gchar *
up_wakeups_get_cmdline (guint pid)
{
gboolean ret;
gchar *filename = NULL;
gchar *cmdline = NULL;
GError *error = NULL;
/* get command line from proc */
filename = g_strdup_printf ("/proc/%i/cmdline", pid);
ret = g_file_get_contents (filename, &cmdline, NULL, &error);
if (!ret) {
g_debug ("failed to get cmdline: %s", error->message);
g_error_free (error);
goto out;
}
out:
g_free (filename);
return cmdline;
}
/**
* up_wakeups_data_item_compare:
**/
static gint
up_wakeups_data_item_compare (UpWakeupItem **item1, UpWakeupItem **item2)
{
gdouble val1;
gdouble val2;
val1 = up_wakeup_item_get_value (*item1);
val2 = up_wakeup_item_get_value (*item2);
if (val1 > val2)
return -1;
if (val1 < val2)
return 1;
return -0;
}
/**
* up_wakeups_data_get_or_create:
**/
static UpWakeupItem *
up_wakeups_data_get_or_create (UpWakeups *wakeups, guint id)
{
guint i;
UpWakeupItem *item;
for (i=0; i<wakeups->priv->data->len; i++) {
item = g_ptr_array_index (wakeups->priv->data, i);
if (up_wakeup_item_get_id (item) == id)
goto out;
}
item = up_wakeup_item_new ();
up_wakeup_item_set_id (item, id);
g_ptr_array_add (wakeups->priv->data, item);
out:
return item;
}
/**
* up_wakeups_data_get_total:
**/
static guint
up_wakeups_data_get_total (UpWakeups *wakeups)
{
guint i;
gfloat total = 0;
UpWakeupItem *item;
for (i=0; i<wakeups->priv->data->len; i++) {
item = g_ptr_array_index (wakeups->priv->data, i);
total += up_wakeup_item_get_value (item);
}
return (guint) total;
}
/**
* up_wakeups_get_total:
*
* Gets the current latency
**/
static gboolean
up_wakeups_get_total (UpExportedWakeups *skeleton,
GDBusMethodInvocation *invocation,
UpWakeups *wakeups)
{
gboolean ret;
/* no capability */
if (!up_exported_wakeups_get_has_capability (skeleton)) {
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"no hardware support");
return TRUE;
}
/* start if not already started */
ret = up_wakeups_timerstats_enable (wakeups);
/* no data */
if (!ret) {
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"cannot enable timerstats");
return TRUE;
}
/* return total averaged */
up_exported_wakeups_complete_get_total (skeleton, invocation, wakeups->priv->total_ave);
return TRUE;
}
/**
* up_wakeups_get_data:
**/
static gboolean
up_wakeups_get_data (UpExportedWakeups *skeleton,
GDBusMethodInvocation *invocation,
UpWakeups *wakeups)
{
guint i;
GPtrArray *array;
UpWakeupItem *item;
GVariantBuilder builder;
/* no capability */
if (!up_exported_wakeups_get_has_capability (skeleton)) {
g_dbus_method_invocation_return_error_literal (invocation,
UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL,
"no hardware support");
return TRUE;
}
/* start if not already started */
up_wakeups_timerstats_enable (wakeups);
/* sort data */
g_ptr_array_sort (wakeups->priv->data, (GCompareFunc) up_wakeups_data_item_compare);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(budss)"));
array = wakeups->priv->data;
for (i = 0; i < array->len; i++) {
item = g_ptr_array_index (array, i);
if (up_wakeup_item_get_value (item) < UP_WAKEUPS_SMALLEST_VALUE)
continue;
g_variant_builder_add (&builder, "(budss)",
up_wakeup_item_get_is_userspace (item),
up_wakeup_item_get_id (item),
up_wakeup_item_get_value (item),
up_wakeup_item_get_cmdline (item),
up_wakeup_item_get_details (item));
}
up_exported_wakeups_complete_get_data (skeleton, invocation,
g_variant_builder_end (&builder));
return TRUE;
}
/**
* up_is_in:
**/
static gboolean
up_is_in (gchar needle, const gchar *delimiters)
{
guint i;
for (i=0; delimiters[i] != '\0'; i++) {
if (delimiters[i] == needle)
return TRUE;
}
return FALSE;
}
/**
* up_strsplit_complete_set:
**/
static GPtrArray *
up_strsplit_complete_set (const gchar *string, const gchar *delimiters, guint max_tokens)
{
guint i;
gboolean ret;
const gchar *start = NULL;
gchar temp_data[100];
guint len;
guint tokens = 0;
GPtrArray *array;
/* find sections not delimited by space */
array = g_ptr_array_new_with_free_func (g_free);
for (i=0; string[i] != '\0'; i++) {
ret = up_is_in (string[i], delimiters);
if (ret) {
/* no character data yet */
if (start == NULL)
continue;
if (tokens == max_tokens - 1) {
g_ptr_array_add (array, g_strdup (start));
break;
}
/* find length of string */
len = &string[i] - start;
if (len > 99)
len = 99;
strncpy (temp_data, start, len);
temp_data[len] = '\0';
/* add to array */
g_ptr_array_add (array, g_strdup (temp_data));
tokens++;
start = NULL;
continue;
}
/* we've got character data */
if (start == NULL)
start = &string[i];
}
return array;
}
/**
* up_wakeups_perhaps_data_changed:
**/
static void
up_wakeups_perhaps_data_changed (UpWakeups *wakeups)
{
guint total;
/* total has changed */
total = up_wakeups_data_get_total (wakeups);
if (total != wakeups->priv->total_old) {
/* no old data, assume this is true */
if (wakeups->priv->total_old == 0)
wakeups->priv->total_ave = total;
else
wakeups->priv->total_ave = UP_WAKEUPS_TOTAL_SMOOTH_FACTOR * (gfloat) (total - wakeups->priv->total_old);
up_exported_wakeups_emit_total_changed (UP_EXPORTED_WAKEUPS (wakeups),
wakeups->priv->total_ave);
}
/* unconditionally emit */
up_exported_wakeups_emit_data_changed (UP_EXPORTED_WAKEUPS (wakeups));
}
/**
* up_wakeups_poll_kernel_cb:
**/
static gboolean
up_wakeups_poll_kernel_cb (UpWakeups *wakeups)
{
guint i;
guint j;
gboolean ret;
gboolean special_ipi;
gchar *data = NULL;
gchar **lines = NULL;
GError *error = NULL;
guint cpus = 0;
const gchar *found;
const gchar *found2;
guint irq;
guint interrupts;
GPtrArray *sections;
UpWakeupItem *item;
g_debug ("event");
/* set all kernel data objs to zero */
for (i=0; i<wakeups->priv->data->len; i++) {
item = g_ptr_array_index (wakeups->priv->data, i);
if (!up_wakeup_item_get_is_userspace (item))
up_wakeup_item_set_value (item, 0.0f);
}
/* get the data */
ret = g_file_get_contents (UP_WAKEUPS_SOURCE_KERNEL, &data, NULL, &error);
if (!ret) {
g_warning ("failed to get data: %s", error->message);
g_error_free (error);
goto out;
}
/* split */
lines = g_strsplit (data, "\n", 0);
/* find out how many processors we have */
sections = up_strsplit_complete_set (lines[0], " ", 0);
cpus = sections->len;
g_ptr_array_unref (sections);
/* get the data from " 9: 29730 365 IO-APIC-fasteoi acpi" */
for (i=1; lines[i] != NULL; i++) {
/* get sections and check correct length */
sections = up_strsplit_complete_set (lines[i], " :", 2 + cpus);
if (sections->len != 2 + cpus)
goto skip;
/* get irq */
special_ipi = TRUE;
found = g_ptr_array_index (sections, 0);
if (strcmp (found, "NMI") == 0)
irq = 0xff0;
else if (strcmp (found, "LOC") == 0)
irq = 0xff1;
else if (strcmp (found, "RES") == 0)
irq = 0xff2;
else if (strcmp (found, "CAL") == 0)
irq = 0xff3;
else if (strcmp (found, "TLB") == 0)
irq = 0xff4;
else if (strcmp (found, "TRM") == 0)
irq = 0xff5;
else if (strcmp (found, "SPU") == 0)
irq = 0xff6;
else if (strcmp (found, "ERR") == 0)
irq = 0xff7;
else if (strcmp (found, "MIS") == 0)
irq = 0xff8;
else {
irq = atoi (found);
special_ipi = FALSE;
}
/* get the number of interrupts over all processors */
interrupts = 0;
for (j=1; j<cpus; j++) {
found = g_ptr_array_index (sections, j);
interrupts += atoi (found);
}
if (interrupts == 0)
goto skip;
/* get the detail string */
found = g_ptr_array_index (sections, cpus+1);
/* save in database */
item = up_wakeups_data_get_or_create (wakeups, irq);
if (up_wakeup_item_get_details (item) == NULL) {
/* remove the interrupt type */
found2 = strstr (found, "IO-APIC-fasteoi");
if (found2 != NULL)
found = g_strchug ((gchar*)found2+16);
found2 = strstr (found, "IO-APIC-edge");
if (found2 != NULL)
found = g_strchug ((gchar*)found2+14);
up_wakeup_item_set_details (item, found);
/* we special */
if (special_ipi)
up_wakeup_item_set_cmdline (item, "kernel-ipi");
else
up_wakeup_item_set_cmdline (item, "interrupt");
up_wakeup_item_set_is_userspace (item, FALSE);
}
/* we report this in minutes, not seconds */
if (up_wakeup_item_get_old (item) > 0)
up_wakeup_item_set_value (item, (interrupts - up_wakeup_item_get_old (item)) / (gfloat) UP_WAKEUPS_POLL_INTERVAL_KERNEL);
up_wakeup_item_set_old (item, interrupts);
skip:
g_ptr_array_unref (sections);
}
/* tell GUI we've changed */
up_wakeups_perhaps_data_changed (wakeups);
out:
g_free (data);
g_strfreev (lines);
return TRUE;
}
/**
* up_wakeups_poll_userspace_cb:
**/
static gboolean
up_wakeups_poll_userspace_cb (UpWakeups *wakeups)
{
guint i;
gboolean ret;
GError *error = NULL;
gchar *data = NULL;
gchar **lines = NULL;
const gchar *string;
UpWakeupItem *item;
GPtrArray *sections;
guint pid;
guint interrupts;
gfloat interval = 5.0f;
gchar *cmdline;
g_debug ("event");
/* set all userspace data objs to zero */
for (i=0; i<wakeups->priv->data->len; i++) {
item = g_ptr_array_index (wakeups->priv->data, i);
if (up_wakeup_item_get_is_userspace (item))
up_wakeup_item_set_value (item, 0.0f);
}
/* get the data */
ret = g_file_get_contents (UP_WAKEUPS_SOURCE_USERSPACE, &data, NULL, &error);
if (!ret) {
g_warning ("failed to get data: %s", error->message);
g_error_free (error);
goto out;
}
/* split */
lines = g_strsplit (data, "\n", 0);
/* get the data from " 9: 29730 365 IO-APIC-fasteoi acpi" */
for (i=0; lines[i] != NULL; i++) {
if (strstr (lines[i], "Timer Stats Version:") != NULL)
continue;
if (strstr (lines[i], "events/sec") != NULL)
continue;
/* get sections */
sections = up_strsplit_complete_set (lines[i], " :", 4);
/* get timeout */
if (strstr (lines[i], "Sample period:") != NULL) {
string = g_ptr_array_index (sections, 2);
interval = atof (string);
g_debug ("interval=%f", interval);
goto skip;
}
/* check correct length */
if (sections->len != 4)
goto skip;
/* if deferred */
string = g_ptr_array_index (sections, 0);
if (strstr (string, "D") != NULL)
goto skip;
interrupts = atoi (string);
if (interrupts == 0)
goto skip;
/* get pid */
string = g_ptr_array_index (sections, 1);
pid = atoi (string);
/* ignore scheduled */
string = g_ptr_array_index (sections, 3);
if (g_str_has_prefix (string, "tick_nohz_"))
goto skip;
if (g_str_has_prefix (string, "tick_setup_sched_timer"))
goto skip;
/* get details */
/* save in database */
item = up_wakeups_data_get_or_create (wakeups, pid);
if (up_wakeup_item_get_details (item) == NULL) {
/* get process name (truncated) */
string = g_ptr_array_index (sections, 2);
if (strcmp (string, "insmod") == 0 ||
strcmp (string, "modprobe") == 0 ||
strcmp (string, "swapper") == 0) {
up_wakeup_item_set_cmdline (item, string);
up_wakeup_item_set_is_userspace (item, FALSE);
} else {
/* try to get a better command line */
cmdline = up_wakeups_get_cmdline (pid);
up_wakeup_item_set_cmdline (item, cmdline);
g_free (cmdline);
if (up_wakeup_item_get_cmdline (item) == NULL ||
up_wakeup_item_get_cmdline (item)[0] == '\0')
up_wakeup_item_set_cmdline (item, string);
up_wakeup_item_set_is_userspace (item, TRUE);
}
string = g_ptr_array_index (sections, 3);
up_wakeup_item_set_details (item, string);
}
/* we report this in minutes, not seconds */
up_wakeup_item_set_value (item, (gfloat) interrupts / interval);
skip:
g_ptr_array_unref (sections);
}
/* tell GUI we've changed */
up_wakeups_perhaps_data_changed (wakeups);
out:
g_free (data);
g_strfreev (lines);
return ret;
}
/**
* up_wakeups_timerstats_disable:
**/
static gboolean
up_wakeups_timerstats_disable (UpWakeups *wakeups)
{
FILE *file;
/* already same state */
if (!wakeups->priv->polling_enabled)
return TRUE;
g_debug ("disabling timer stats");
/* clear polling */
if (wakeups->priv->poll_kernel_id != 0) {
g_source_remove (wakeups->priv->poll_kernel_id);
wakeups->priv->poll_kernel_id = 0;
}
if (wakeups->priv->poll_userspace_id != 0) {
g_source_remove (wakeups->priv->poll_userspace_id);
wakeups->priv->poll_userspace_id = 0;
}
if (wakeups->priv->disable_id != 0) {
g_source_remove (wakeups->priv->disable_id);
wakeups->priv->disable_id = 0;
}
file = fopen (UP_WAKEUPS_SOURCE_USERSPACE, "w");
if (file == NULL)
return FALSE;
fprintf (file, "0\n");
fclose (file);
wakeups->priv->polling_enabled = FALSE;
return TRUE;
}
/**
* up_wakeups_disable_cb:
**/
static gboolean
up_wakeups_disable_cb (UpWakeups *wakeups)
{
g_debug ("disabling timer stats as we are idle");
up_wakeups_timerstats_disable (wakeups);
/* never repeat */
return FALSE;
}
/**
* up_wakeups_timerstats_enable:
**/
static gboolean
up_wakeups_timerstats_enable (UpWakeups *wakeups)
{
FILE *file;
/* reset timeout */
if (wakeups->priv->disable_id != 0)
g_source_remove (wakeups->priv->disable_id);
wakeups->priv->disable_id =
g_timeout_add_seconds (UP_WAKEUPS_DISABLE_INTERVAL,
(GSourceFunc) up_wakeups_disable_cb, wakeups);
g_source_set_name_by_id (wakeups->priv->disable_id, "[upower] up_wakeups_disable_cb");
/* already same state */
if (wakeups->priv->polling_enabled)
return TRUE;
g_debug ("enabling timer stats");
/* enable timer stats */
file = fopen (UP_WAKEUPS_SOURCE_USERSPACE, "w");
if (file == NULL)
return FALSE;
fprintf (file, "1\n");
fclose (file);
/* setup polls */
wakeups->priv->poll_kernel_id =
g_timeout_add_seconds (UP_WAKEUPS_POLL_INTERVAL_KERNEL,
(GSourceFunc) up_wakeups_poll_kernel_cb, wakeups);
g_source_set_name_by_id (wakeups->priv->poll_kernel_id, "[upower] up_wakeups_poll_kernel_cb");
wakeups->priv->poll_userspace_id =
g_timeout_add_seconds (UP_WAKEUPS_POLL_INTERVAL_USERSPACE,
(GSourceFunc) up_wakeups_poll_userspace_cb, wakeups);
g_source_set_name_by_id (wakeups->priv->poll_userspace_id, "[upower] up_wakeups_poll_userspace_cb");
wakeups->priv->polling_enabled = TRUE;
return TRUE;
}
/**
* up_wakeups_class_init:
**/
static void
up_wakeups_class_init (UpWakeupsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = up_wakeups_finalize;
}
/**
* up_wakeups_init:
**/
static void
up_wakeups_init (UpWakeups *wakeups)
{
wakeups->priv = up_wakeups_get_instance_private (wakeups);
wakeups->priv->data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
/* test if we have an interface */
if (g_file_test (UP_WAKEUPS_SOURCE_KERNEL, G_FILE_TEST_EXISTS) ||
g_file_test (UP_WAKEUPS_SOURCE_KERNEL, G_FILE_TEST_EXISTS)) {
up_exported_wakeups_set_has_capability (UP_EXPORTED_WAKEUPS (wakeups), TRUE);
}
g_signal_connect (wakeups, "handle-get-data",
G_CALLBACK (up_wakeups_get_data), wakeups);
g_signal_connect (wakeups, "handle-get-total",
G_CALLBACK (up_wakeups_get_total), wakeups);
}
/**
* up_wakeups_finalize:
**/
static void
up_wakeups_finalize (GObject *object)
{
UpWakeups *wakeups;
g_return_if_fail (object != NULL);
g_return_if_fail (UP_IS_WAKEUPS (object));
wakeups = UP_WAKEUPS (object);
wakeups->priv = up_wakeups_get_instance_private (wakeups);
/* stop timerstats */
up_wakeups_timerstats_disable (wakeups);
g_ptr_array_unref (wakeups->priv->data);
G_OBJECT_CLASS (up_wakeups_parent_class)->finalize (object);
}
/**
* up_wakeups_new:
**/
UpWakeups *
up_wakeups_new (void)
{
return g_object_new (UP_TYPE_WAKEUPS, NULL);
}
void
up_wakeups_register (UpWakeups *wakeups,
GDBusConnection *connection)
{
GError *error = NULL;
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (wakeups),
connection,
"/org/freedesktop/UPower/Wakeups",
&error);
if (error != NULL) {
g_critical ("Cannot register wakeups on system bus: %s", error->message);
g_error_free (error);
}
}

View file

@ -1,57 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __UP_WAKEUPS_H
#define __UP_WAKEUPS_H
#include <dbus/up-wakeups-generated.h>
G_BEGIN_DECLS
#define UP_TYPE_WAKEUPS (up_wakeups_get_type ())
#define UP_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UP_TYPE_WAKEUPS, UpWakeups))
#define UP_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), UP_TYPE_WAKEUPS, UpWakeupsClass))
#define UP_IS_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UP_TYPE_WAKEUPS))
#define UP_IS_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), UP_TYPE_WAKEUPS))
#define UP_WAKEUPS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), UP_TYPE_WAKEUPS, UpWakeupsClass))
typedef struct UpWakeupsPrivate UpWakeupsPrivate;
typedef struct
{
UpExportedWakeupsSkeleton parent;
UpWakeupsPrivate *priv;
} UpWakeups;
typedef struct
{
UpExportedWakeupsSkeletonClass parent_class;
} UpWakeupsClass;
UpWakeups *up_wakeups_new (void);
GType up_wakeups_get_type (void);
void up_wakeups_register (UpWakeups *wakeups,
GDBusConnection *connection);
G_END_DECLS
#endif /* __UP_WAKEUPS_H */

View file

@ -181,62 +181,6 @@ up_tool_do_monitor (UpClient *client)
return FALSE;
}
/**
* up_tool_print_wakeup_item:
**/
static void
up_tool_print_wakeup_item (UpWakeupItem *item)
{
g_print ("userspace:%i id:%i, interrupts:%.1f, cmdline:%s, details:%s\n",
up_wakeup_item_get_is_userspace (item),
up_wakeup_item_get_id (item),
up_wakeup_item_get_value (item),
up_wakeup_item_get_cmdline (item),
up_wakeup_item_get_details (item));
}
/**
* up_tool_show_wakeups:
**/
static gboolean
up_tool_show_wakeups (void)
{
guint i;
gboolean ret;
UpWakeups *wakeups;
UpWakeupItem *item;
guint total;
GPtrArray *array;
/* create new object */
wakeups = up_wakeups_new ();
/* do we have support? */
ret = up_wakeups_get_has_capability (wakeups);
if (!ret) {
g_print ("No wakeup capability\n");
goto out;
}
/* get total */
total = up_wakeups_get_total_sync (wakeups, NULL, NULL);
g_print ("Total wakeups per minute: %i\n", total);
/* get data */
array = up_wakeups_get_data_sync (wakeups, NULL, NULL);
if (array == NULL)
goto out;
g_print ("Wakeup sources:\n");
for (i=0; i<array->len; i++) {
item = g_ptr_array_index (array, i);
up_tool_print_wakeup_item (item);
}
g_ptr_array_unref (array);
out:
g_object_unref (wakeups);
return ret;
}
/**
* main:
**/
@ -247,7 +191,6 @@ main (int argc, char **argv)
guint i;
GOptionContext *context;
gboolean opt_dump = FALSE;
gboolean opt_wakeups = FALSE;
gboolean opt_enumerate = FALSE;
gboolean opt_monitor = FALSE;
gchar *opt_show_info = FALSE;
@ -262,7 +205,6 @@ main (int argc, char **argv)
const GOptionEntry entries[] = {
{ "enumerate", 'e', 0, G_OPTION_ARG_NONE, &opt_enumerate, _("Enumerate objects paths for devices"), NULL },
{ "dump", 'd', 0, G_OPTION_ARG_NONE, &opt_dump, _("Dump all parameters for all objects"), NULL },
{ "wakeups", 'w', 0, G_OPTION_ARG_NONE, &opt_wakeups, _("Get the wakeup data"), NULL },
{ "monitor", 'm', 0, G_OPTION_ARG_NONE, &opt_monitor, _("Monitor activity from the power daemon"), NULL },
{ "monitor-detail", 0, 0, G_OPTION_ARG_NONE, &opt_monitor_detail, _("Monitor with detail"), NULL },
{ "show-info", 'i', 0, G_OPTION_ARG_STRING, &opt_show_info, _("Show information about object path"), NULL },
@ -301,13 +243,6 @@ main (int argc, char **argv)
goto out;
}
/* wakeups */
if (opt_wakeups) {
up_tool_show_wakeups ();
retval = EXIT_SUCCESS;
goto out;
}
if (opt_enumerate || opt_dump) {
GPtrArray *devices;
devices = up_client_get_devices2 (client);