New e-d-s backend which indexes all local addressbooks and calendars.
[beagle.git] / Util / SystemInformation.cs
blobc9f8646dc9e0e8a88db7da83fce1f644254bb91b
1 //
2 // SystemInformation.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.Diagnostics;
30 using System.Globalization;
31 using System.IO;
32 using System.Runtime.InteropServices;
33 using System.Text.RegularExpressions;
34 using Mono.Posix;
36 namespace Beagle.Util {
38 public class SystemInformation {
40 [DllImport ("libc", SetLastError=true)]
41 static extern int getloadavg (double[] loadavg, int nelem);
43 const double loadavg_poll_delay = 3;
44 static DateTime proc_loadavg_time = DateTime.MinValue;
45 static double cached_loadavg_1min = -1;
46 static double cached_loadavg_5min = -1;
47 static double cached_loadavg_15min = -1;
49 static private void CheckLoadAverage ()
51 // Only call getloadavg() at most once every 10 seconds
52 if ((DateTime.Now - proc_loadavg_time).TotalSeconds < loadavg_poll_delay)
53 return;
55 double [] loadavg = new double [3];
56 int retval = getloadavg (loadavg, 3);
58 if (retval == -1)
59 throw new IOException ("Could not get system load average: " + Syscall.strerror (Marshal.GetLastWin32Error ()));
60 else if (retval != 3)
61 throw new IOException ("Could not get system load average: getloadavg() returned an unexpected number of samples");
63 cached_loadavg_1min = loadavg [0];
64 cached_loadavg_5min = loadavg [1];
65 cached_loadavg_15min = loadavg [2];
67 proc_loadavg_time = DateTime.Now;
70 static public double LoadAverageOneMinute {
71 get {
72 CheckLoadAverage ();
73 return cached_loadavg_1min;
77 static public double LoadAverageFiveMinute {
78 get {
79 CheckLoadAverage ();
80 return cached_loadavg_5min;
84 static public double LoadAverageFifteenMinute {
85 get {
86 CheckLoadAverage ();
87 return cached_loadavg_15min;
91 ///////////////////////////////////////////////////////////////
93 const double screensaver_poll_delay = 1;
94 static DateTime screensaver_time = DateTime.MinValue;
95 static bool cached_screensaver_running = false;
96 static double cached_screensaver_idle_time = 0;
98 private enum ScreenSaverState {
99 Off = 0,
100 On = 1,
101 Cycle = 2,
102 Disabled = 3
105 private enum ScreenSaverKind {
106 Blanked = 0,
107 Internal = 1,
108 External = 2
111 [DllImport ("libsysteminfoglue.so")]
112 extern static unsafe int screensaver_info (ScreenSaverState *state,
113 ScreenSaverKind *kind,
114 ulong *til_or_since,
115 ulong *idle);
117 static private void CheckScreenSaver ()
119 if ((DateTime.Now - screensaver_time).TotalSeconds < screensaver_poll_delay)
120 return;
122 ScreenSaverState state;
123 ScreenSaverKind kind;
124 ulong til_or_since = 0, idle = 0;
125 int retval;
127 unsafe {
128 retval = screensaver_info (&state, &kind, &til_or_since, &idle);
131 if (retval != 0) {
132 cached_screensaver_running = (state == ScreenSaverState.On);
133 cached_screensaver_idle_time = idle / 1000.0;
134 } else {
135 cached_screensaver_running = false;
136 cached_screensaver_idle_time = 0;
139 screensaver_time = DateTime.Now;
142 static public bool ScreenSaverRunning {
143 get {
144 CheckScreenSaver ();
145 return cached_screensaver_running;
149 // returns number of seconds since input was received
150 // from the user on any input device
151 static public double InputIdleTime {
152 get {
153 CheckScreenSaver ();
154 return cached_screensaver_idle_time;
158 ///////////////////////////////////////////////////////////////
160 const double acpi_poll_delay = 30;
161 const string proc_ac_state_filename = "/proc/acpi/ac_adapter/AC/state";
162 const string ac_present_string = "on-line";
163 static bool proc_ac_state_exists = true;
164 static DateTime using_battery_time = DateTime.MinValue;
165 static bool using_battery;
167 static public void CheckAcpi ()
169 if (! proc_ac_state_exists)
170 return;
172 if ((DateTime.Now - using_battery_time).TotalSeconds < acpi_poll_delay)
173 return;
175 if (! File.Exists (proc_ac_state_filename)) {
176 proc_ac_state_exists = false;
177 using_battery = false;
178 return;
181 Stream stream = new FileStream (proc_ac_state_filename,
182 System.IO.FileMode.Open,
183 FileAccess.Read,
184 FileShare.Read);
185 TextReader reader = new StreamReader (stream);
187 string line = reader.ReadLine ();
188 using_battery = (line != null) && (line.IndexOf (ac_present_string) == -1);
190 reader.Close ();
191 stream.Close ();
193 using_battery_time = DateTime.Now;
196 static public bool UsingBattery {
197 get {
198 CheckAcpi ();
199 return using_battery;
203 ///////////////////////////////////////////////////////////////
205 [DllImport ("libsysteminfoglue.so")]
206 extern static int get_vmsize ();
208 [DllImport ("libsysteminfoglue.so")]
209 extern static int get_vmrss ();
211 static public int VmSize {
212 get { return get_vmsize (); }
215 static public int VmRss {
216 get { return get_vmrss (); }
219 static private int disk_stats_read_reqs;
220 static private int disk_stats_write_reqs;
221 static private int disk_stats_read_bytes;
222 static private int disk_stats_write_bytes;
224 static private DateTime disk_stats_time = DateTime.MinValue;
225 static private double disk_stats_delay = 1.0;
227 static private uint major, minor;
229 // Update the disk statistics with data for block device on the (major,minor) pair.
230 static private void UpdateDiskStats ()
232 string buffer;
234 if (major == 0)
235 return;
237 // We only refresh the stats once per second
238 if ((DateTime.Now - disk_stats_time).TotalSeconds < disk_stats_delay)
239 return;
241 // Read in all of the disk stats
242 using (StreamReader stream = new StreamReader ("/proc/diskstats"))
243 buffer = stream.ReadToEnd ();
245 // Find our partition and parse it
246 const string REGEX = "[\\s]+{0}[\\s]+{1}[\\s]+[a-zA-Z0-9]+[\\s]+([0-9]+)[\\s]+([0-9]+)[\\s]+([0-9]+)[\\s]+([0-9]+)";
247 string regex = String.Format (REGEX, major, minor);
248 Regex r = new Regex (regex, RegexOptions.IgnoreCase | RegexOptions.Compiled);
249 for (System.Text.RegularExpressions.Match m = r.Match (buffer); m.Success; m = m.NextMatch ()) {
250 disk_stats_read_reqs = Convert.ToInt32 (m.Groups[1].ToString ());
251 disk_stats_read_bytes = Convert.ToInt32 (m.Groups[2].ToString ());
252 disk_stats_write_reqs = Convert.ToInt32 (m.Groups[3].ToString ());
253 disk_stats_write_bytes = Convert.ToInt32 (m.Groups[4].ToString ());
256 disk_stats_time = DateTime.Now;
259 // Get the (major,minor) pair for the block device from which the index is mounted.
260 static private void GetIndexDev ()
262 Mono.Posix.Stat stat = new Mono.Posix.Stat ();
263 if (Mono.Posix.Syscall.stat (PathFinder.StorageDir, out stat) != 0)
264 return;
266 major = (uint) stat.Device >> 8;
267 minor = (uint) stat.Device & 0xff;
270 static public int DiskStatsReadReqs {
271 get {
272 if (major == 0)
273 GetIndexDev ();
274 UpdateDiskStats ();
275 return disk_stats_read_reqs;
279 static public int DiskStatsReadBytes {
280 get {
281 if (major == 0)
282 GetIndexDev ();
283 UpdateDiskStats ();
284 return disk_stats_read_bytes;
288 static public int DiskStatsWriteReqs {
289 get {
290 if (major == 0)
291 GetIndexDev ();
292 UpdateDiskStats ();
293 return disk_stats_write_reqs;
297 static public int DiskStatsWriteBytes {
298 get {
299 if (major == 0)
300 GetIndexDev ();
301 UpdateDiskStats ();
302 return disk_stats_write_bytes;
306 static public bool IsPathOnBlockDevice (string path)
308 Mono.Posix.Stat stat;
309 if (Mono.Posix.Syscall.stat (path, out stat) != 0)
310 return false;
312 return (stat.Device >> 8 != 0);
315 #if false
316 static void Main ()
318 Gtk.Application.Init ();
319 while (true) {
320 Console.WriteLine ("{0} {1} {2} {3} {4} {5} {6} {7}",
321 LoadAverageOneMinute,
322 LoadAverageFiveMinute,
323 LoadAverageFifteenMinute,
324 ScreenSaverRunning,
325 InputIdleTime,
326 UsingBattery,
327 DiskStatsReadReqs,
328 VmSize);
329 System.Threading.Thread.Sleep (1000);
332 #endif