diff --git a/examples/Makefile.am b/examples/Makefile.am index de6e6ef5..4567e383 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -8,7 +8,7 @@ DEFS = @DEFS@ noinst_PROGRAMS = first second pprint procargs df netlist \ mountlist procmap netload sysdeps timings \ - openfiles smp proclist mem wd + openfiles smp proclist mem wd affinity first_SOURCES = first.c first_LDADD = $(top_builddir)/lib/libgtop-2.0.la @@ -58,3 +58,5 @@ wd_LDADD = $(top_builddir)/lib/libgtop-2.0.la mem_SOURCE = mem.c mem_LDADD = $(top_builddir)/lib/libgtop-2.0.la +affinity_SOURCES = affinity.c +affinity_LDADD = $(top_builddir)/lib/libgtop-2.0.la diff --git a/examples/affinity.c b/examples/affinity.c new file mode 100644 index 00000000..cd670dae --- /dev/null +++ b/examples/affinity.c @@ -0,0 +1,34 @@ +#include +#include + +#include +#include + +int main(int argc, char **argv) +{ + pid_t pid; + glibtop_proc_affinity buf; + guint16 *cpus; + size_t i; + + if (argc < 2 || !(pid = strtoul(argv[1], NULL, 0))) + pid = getpid(); + + glibtop_init(); + + cpus = glibtop_get_proc_affinity(&buf, pid); + + g_print("Process %u:\n" + " - all: %d\n", + (unsigned)pid, buf.all); + + for (i = 0; i != buf.number; ++i) + g_print(" - CPU#%u is set\n", cpus[i]); + + g_free(cpus); + + glibtop_close(); + + return 0; +} + diff --git a/features.def b/features.def index 64e578ec..22474005 100644 --- a/features.def +++ b/features.def @@ -23,4 +23,5 @@ void|netload|ulong(if_flags,mtu,subnet,address,packets_in,packets_out,packets_to void|ppp|ulong(state,bytes_in,bytes_out)|ushort(device) char **|netlist|unsigned(number) char **|proc_wd|ulong(number),str(root),str(exe)|pid_t(pid) +guint16*|proc_affinity|ulong(number),int(all)|pid_t(pid) diff --git a/include/glibtop/Makefile.am b/include/glibtop/Makefile.am index e7b13360..84359d09 100644 --- a/include/glibtop/Makefile.am +++ b/include/glibtop/Makefile.am @@ -8,7 +8,7 @@ glibtop_HEADERS = close.h loadavg.h prockernel.h procstate.h \ procsignal.h union.h gnuserv.h \ parameter.h mountlist.h fsusage.h procmap.h signal.h \ sysinfo.h ppp.h procargs.h netload.h \ - procwd.h \ + procwd.h procaffinity.h \ netlist.h procopenfiles.h open.h noinst_HEADERS = error.h write.h read_data.h read.h init_hooks.h diff --git a/include/glibtop/command.h b/include/glibtop/command.h index bd9667e8..e0f859e5 100644 --- a/include/glibtop/command.h +++ b/include/glibtop/command.h @@ -58,8 +58,9 @@ G_BEGIN_DECLS #define GLIBTOP_CMND_NETLIST 24 #define GLIBTOP_CMND_PROC_OPEN_FILES 25 #define GLIBTOP_CMND_PROC_WD 26 +#define GLIBTOP_CMND_PROC_AFFINITY 27 -#define GLIBTOP_MAX_CMND 27 +#define GLIBTOP_MAX_CMND 28 #define _GLIBTOP_PARAM_SIZE 16 diff --git a/include/glibtop/procaffinity.h b/include/glibtop/procaffinity.h new file mode 100644 index 00000000..e5733721 --- /dev/null +++ b/include/glibtop/procaffinity.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2007 Benoît Dejean + This file is part of LibGTop 2. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_PROCAFFINITY_H__ +#define __GLIBTOP_PROCAFFINITY_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _glibtop_proc_affinity glibtop_proc_affinity; + +#define GLIBTOP_PROC_AFFINITY_NUMBER 0 +#define GLIBTOP_PROC_AFFINITY_ALL 1 + +struct _glibtop_proc_affinity +{ + guint64 flags; + guint32 number; + gboolean all; +}; + + +guint16 * glibtop_get_proc_affinity(glibtop_proc_affinity *buf, pid_t pid); +guint16 * glibtop_get_proc_affinity_l(glibtop *server, glibtop_proc_affinity *buf, pid_t pid); + + +#if GLIBTOP_SUID_PROC_AFFINITY + +#define glibtop_get_proc_affinity_r glibtop_get_proc_affinity_p +void _glibtop_init_proc_affinity_p(glibtop *server); +guint16 * glibtop_get_proc_affinity_p(glibtop *server, glibtop_proc_affinity *buf, pid_t pid); + +#else + +#define glibtop_get_proc_affinity_r glibtop_get_proc_affinity_s +void _glibtop_init_proc_affinity_s(glibtop *server); +guint16 * glibtop_get_proc_affinity_s(glibtop *server, glibtop_proc_affinity *buf, pid_t pid); + +#endif + +G_END_DECLS + +#endif diff --git a/include/glibtop/sysdeps.h b/include/glibtop/sysdeps.h index 40f0b6b2..1060d1c9 100644 --- a/include/glibtop/sysdeps.h +++ b/include/glibtop/sysdeps.h @@ -52,8 +52,9 @@ G_BEGIN_DECLS #define GLIBTOP_SYSDEPS_NETLIST 23 #define GLIBTOP_SYSDEPS_PROC_OPEN_FILES 24 #define GLIBTOP_SYSDEPS_PROC_WD 25 +#define GLIBTOP_SYSDEPS_PROC_AFFINITY 26 -#define GLIBTOP_MAX_SYSDEPS 26 +#define GLIBTOP_MAX_SYSDEPS 27 #define GLIBTOP_SYSDEPS_ALL ((1 << GLIBTOP_MAX_SYSDEPS) - 1) @@ -88,6 +89,7 @@ struct _glibtop_sysdeps guint64 netload; /* glibtop_netload */ guint64 ppp; /* glibtop_ppp */ guint64 proc_wd; /* glibtop_proc_wd */ + guint64 proc_affinity; /* glibtop_proc_affinity */ }; void glibtop_get_sysdeps (glibtop_sysdeps *buf); diff --git a/include/glibtop/union.h b/include/glibtop/union.h index 39da4640..b0eb33de 100644 --- a/include/glibtop/union.h +++ b/include/glibtop/union.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,7 @@ union _glibtop_union glibtop_ppp ppp; glibtop_proc_open_files proc_open_files; glibtop_proc_wd proc_wd; + glibtop_proc_affinity proc_affinity; }; G_END_DECLS diff --git a/lib/libgtop.sym b/lib/libgtop.sym index 9ba1f337..4cfac3e4 100644 --- a/lib/libgtop.sym +++ b/lib/libgtop.sym @@ -42,6 +42,10 @@ glibtop_get_ppp glibtop_get_ppp_l glibtop_get_ppp_p glibtop_get_ppp_s +glibtop_get_proc_affinity +glibtop_get_proc_affinity_l +glibtop_get_proc_affinity_p +glibtop_get_proc_affinity_s glibtop_get_proc_args glibtop_get_proc_args_l glibtop_get_proc_args_p @@ -53,10 +57,6 @@ glibtop_get_proc_kernel glibtop_get_proc_kernel_l glibtop_get_proc_kernel_p glibtop_get_proc_kernel_s -glibtop_get_proclist -glibtop_get_proclist_l -glibtop_get_proclist_p -glibtop_get_proclist_s glibtop_get_proc_map glibtop_get_proc_map_l glibtop_get_proc_map_p @@ -93,6 +93,10 @@ glibtop_get_proc_wd glibtop_get_proc_wd_l glibtop_get_proc_wd_p glibtop_get_proc_wd_s +glibtop_get_proclist +glibtop_get_proclist_l +glibtop_get_proclist_p +glibtop_get_proclist_s glibtop_get_sem_limits glibtop_get_sem_limits_l glibtop_get_sem_limits_p @@ -127,4 +131,4 @@ glibtop_open_s glibtop_server_features glibtop_set_parameter_l glibtop_set_parameter_p -glibtop_sys_siglist +glibtop_sys_siglist \ No newline at end of file diff --git a/lib/sysdeps.c b/lib/sysdeps.c index 1540a601..87544f3e 100644 --- a/lib/sysdeps.c +++ b/lib/sysdeps.c @@ -47,6 +47,7 @@ GLIBTOP_SUID_PROC_MAP + GLIBTOP_SUID_NETLOAD + GLIBTOP_SUID_NETLIST + GLIBTOP_SUID_PROC_WD + +GLIBTOP_SUID_PROC_AFFINITY + GLIBTOP_SUID_PPP; const _glibtop_init_func_t _glibtop_init_hook_s [] = { @@ -113,6 +114,9 @@ const _glibtop_init_func_t _glibtop_init_hook_s [] = { #if !GLIBTOP_SUID_PROC_WD _glibtop_init_proc_wd_s, #endif +#if !GLIBTOP_SUID_PROC_AFFINITY + _glibtop_init_proc_affinity_s, +#endif #if !GLIBTOP_SUID_PPP _glibtop_init_ppp_s, #endif @@ -183,6 +187,9 @@ const _glibtop_init_func_t _glibtop_init_hook_p [] = { #if GLIBTOP_SUID_PROC_WD _glibtop_init_proc_wd_p, #endif +#if GLIBTOP_SUID_PROC_AFFINITY + _glibtop_init_proc_affinity_p, +#endif #if GLIBTOP_SUID_PPP _glibtop_init_ppp_p, #endif diff --git a/src/daemon/server.c b/src/daemon/server.c index 9af133c0..5553423a 100644 --- a/src/daemon/server.c +++ b/src/daemon/server.c @@ -53,6 +53,7 @@ GLIBTOP_SUID_PROC_MAP + GLIBTOP_SUID_NETLOAD + GLIBTOP_SUID_NETLIST + GLIBTOP_SUID_PROC_WD + +GLIBTOP_SUID_PROC_AFFINITY + GLIBTOP_SUID_PPP; #include diff --git a/sysdeps/common/default.c b/sysdeps/common/default.c index ae66c01f..71db0746 100644 --- a/sysdeps/common/default.c +++ b/sysdeps/common/default.c @@ -368,3 +368,17 @@ glibtop_get_proc_wd(glibtop_proc_wd *buf, pid_t pid) } +/** + * glibtop_get_proc_affinity: + * @buf: + * @pid: Process id to get the affinity + * + * Get the processor affinity list for a process + * + * Returns: A list of processor ID of 'buf.number' elements. + */ +guint16 * +glibtop_get_proc_affinity(glibtop_proc_affinity *buf, pid_t pid) +{ + return glibtop_get_proc_affinity_l(glibtop_global_server, buf, pid); +} diff --git a/sysdeps/linux/Makefile.am b/sysdeps/linux/Makefile.am index 6b94337b..09114d75 100644 --- a/sysdeps/linux/Makefile.am +++ b/sysdeps/linux/Makefile.am @@ -8,7 +8,8 @@ libgtop_sysdeps_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ proctime.c procmem.c procsignal.c prockernel.c \ procsegment.c procargs.c procmap.c siglist.c \ sysinfo.c netload.c ppp.c glibtop_private.c \ - fsusage.c netlist.c procopenfiles.c procwd.c + fsusage.c netlist.c procopenfiles.c procwd.c \ + procaffinity.c libgtop_sysdeps_2_0_la_LIBADD = @GLIB_LIBS@ diff --git a/sysdeps/linux/glibtop_server.h b/sysdeps/linux/glibtop_server.h index 3f9980d6..116547fe 100644 --- a/sysdeps/linux/glibtop_server.h +++ b/sysdeps/linux/glibtop_server.h @@ -43,6 +43,7 @@ #define GLIBTOP_SUID_NETLOAD 0 #define GLIBTOP_SUID_NETLIST 0 #define GLIBTOP_SUID_PROC_WD 0 +#define GLIBTOP_SUID_PROC_AFFINITY 0 #define GLIBTOP_SUID_PPP 0 #define GLIBTOP_SUID_PROC_FILE 0 diff --git a/sysdeps/linux/procaffinity.c b/sysdeps/linux/procaffinity.c new file mode 100644 index 00000000..81b90674 --- /dev/null +++ b/sysdeps/linux/procaffinity.c @@ -0,0 +1,69 @@ +/* Copyright (C) 2007 Benoît Dejean + This file is part of LibGTop 2. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include + +#include + + +void +_glibtop_init_proc_affinity_s(glibtop *server) +{ + server->sysdeps.proc_affinity = + (1 << GLIBTOP_PROC_AFFINITY_NUMBER) | + (1 << GLIBTOP_PROC_AFFINITY_ALL); + +} + + +guint16 * +glibtop_get_proc_affinity_s(glibtop *server, glibtop_proc_affinity *buf, pid_t pid) +{ + cpu_set_t set; + size_t i; + GArray* cpus; + + memset(buf, 0, sizeof *buf); + + if (sched_getaffinity(pid, sizeof set, &set) == -1) { + glibtop_error_r(server, "sched_getaffinity failed"); + return NULL; + } + + cpus = g_array_new(FALSE, FALSE, sizeof(guint16)); + + for (i = 0; i < MIN(CPU_SETSIZE, (size_t)(server->ncpu + 1)); i++) { + if (CPU_ISSET(i, &set)) { + guint16 n = i; + g_array_append_val(cpus, n); + } + } + + buf->number = cpus->len; + buf->all = (cpus->len == (size_t)(server->ncpu + 1)); + buf->flags = (1 << GLIBTOP_PROC_AFFINITY_NUMBER) + | (1 << GLIBTOP_PROC_AFFINITY_ALL); + + return (guint16*) g_array_free(cpus, FALSE); +} +