]> git.vpit.fr Git - perl/modules/Linux-SysInfo.git/blobdiff - SysInfo.xs
This is 0.15
[perl/modules/Linux-SysInfo.git] / SysInfo.xs
index f7509c419a4edf65d0d1bc7bd95394a1dbc80535..8e4f0dc24542bee2ee4685f51f43802472c12b1e 100644 (file)
@@ -1,41 +1,69 @@
+/* This file is part of the Linux::SysInfo Perl module.
+ * See http://search.cpan.org/dist/Linux-SysInfo/
+ * Vincent Pit - 2007 */
+
+#include <linux/version.h> /* LINUX_VERSION_CODE, KERNEL_VERSION() */
+#include <sys/sysinfo.h>   /* <struct sysinfo>, sysinfo(), SI_LOAD_SHIFT */
+
+#define PERL_NO_GET_CONTEXT
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
 
-#include <linux/version.h> /* LINUX_VERSION_CODE, KERNEL_VERSION() */
-#include <sys/sysinfo.h>   /* <struct sysinfo>, sysinfo(), SI_LOAD_SHIFT */
+#define __PACKAGE__     "Linux::SysInfo"
+#define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1)
+
+/* --- Extended fields ----------------------------------------------------- */
 
 #if ((defined(__i386__) || defined(__x86_64__)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23))) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 48))
-# define SYSINFO_EXTENDED 1
+# define LS_HAS_EXTENDED 1
+#else
+# define LS_HAS_EXTENDED 0
+#endif
+
+/* --- Keys ---------------------------------------------------------------- */
+
+#define LS_KEY(K)            (ls_key_##K##_sv)
+#if PERL_REVISION <= 4 || (PERL_REVISION == 5 && PERL_VERSION <= 6)
+/* newSVpvn_share doesn't exist in perl-5.6.x */
+# define LS_HASH(K)          (ls_key_##K##_hash)
+# define LS_KEY_DECLARE(K)   STATIC const char LS_KEY(K)[] = #K; \
+                             STATIC U32 LS_HASH(K) = 0
+# define LS_KEY_DEFINE(K)    PERL_HASH(LS_HASH(K), LS_KEY(K), sizeof(#K)-1)
+# define LS_KEY_STORE(H,K,V) hv_store((H), LS_KEY(K), sizeof(#K)-1, \
+                                      (V), LS_HASH(K))
 #else
-# define SYSINFO_EXTENDED 0
+# if PERL_REVISION > 5 || (PERL_REVISION == 5 && (PERL_VERSION > 9 || (PERL_VERSION == 9 && PERL_SUBVERSION >= 3)))
+/* From perl-5.9.3 (#24802), the key is only a SVt_PV and one can get the hash
+ * value with the SvSHARED_HASH() macro. */
+#  define LS_HASH(K)         SvSHARED_HASH(LS_KEY(K))
+# else
+/* Before, the key was a SVt_PVIV and the hash was stored in the UV field. */
+#  define LS_HASH(K)         SvUVX(LS_KEY(K))
+# endif
+# define LS_KEY_DECLARE(K)   STATIC SV *LS_KEY(K) = NULL
+# define LS_KEY_DEFINE(K)    LS_KEY(K) = newSVpvn_share(#K, sizeof(#K)-1, 0)
+# define LS_KEY_STORE(H,K,V) hv_store_ent((H), LS_KEY(K), (V), LS_HASH(K))
 #endif
 
-typedef struct {
- const char* key;
- U32 klen;
- U32 hash;
-} sysinfo_key;
-
-#define SYSINFO_KEY_SET_HASH(S) PERL_HASH((S).hash, (S).key, (S).klen)
-#define SYSINFO_KEY_STORE(H,S,V) hv_store((H), (S).key, (S).klen, (V), (S).hash)
-
-static sysinfo_key key_uptime    = { "uptime",    6, 0 };
-static sysinfo_key key_load1     = { "load1",     5, 0 };
-static sysinfo_key key_load5     = { "load5",     5, 0 };
-static sysinfo_key key_load15    = { "load15",    6, 0 };
-static sysinfo_key key_totalram  = { "totalram",  8, 0 };
-static sysinfo_key key_freeram   = { "freeram",   7, 0 };
-static sysinfo_key key_sharedram = { "sharedram", 9, 0 };
-static sysinfo_key key_bufferram = { "bufferram", 9, 0 };
-static sysinfo_key key_totalswap = { "totalswap", 9, 0 };
-static sysinfo_key key_freeswap  = { "freeswap",  8, 0 };
-static sysinfo_key key_procs     = { "procs",     5, 0 };
-#if SYSINFO_EXTENDED
-static sysinfo_key key_totalhigh = { "totalhigh", 9, 0 };
-static sysinfo_key key_freehigh  = { "freehigh",  8, 0 };
-static sysinfo_key key_mem_unit  = { "mem_unit",  8, 0 };
-#endif /* SYSINFO_EXTENDED */
+LS_KEY_DECLARE(uptime);
+LS_KEY_DECLARE(load1);
+LS_KEY_DECLARE(load5);
+LS_KEY_DECLARE(load15);
+LS_KEY_DECLARE(totalram);
+LS_KEY_DECLARE(freeram);
+LS_KEY_DECLARE(sharedram);
+LS_KEY_DECLARE(bufferram);
+LS_KEY_DECLARE(totalswap);
+LS_KEY_DECLARE(freeswap);
+LS_KEY_DECLARE(procs);
+#if LS_HAS_EXTENDED
+LS_KEY_DECLARE(totalhigh);
+LS_KEY_DECLARE(freehigh);
+LS_KEY_DECLARE(mem_unit);
+#endif /* LS_HAS_EXTENDED */
+
+/* --- XS ------------------------------------------------------------------ */
 
 MODULE = Linux::SysInfo              PACKAGE = Linux::SysInfo
 
@@ -44,63 +72,61 @@ PROTOTYPES: ENABLE
 BOOT:
 {
  HV *stash;
- stash = gv_stashpv("Linux::SysInfo", TRUE);
- newCONSTSUB(stash, "LS_HAS_EXTENDED", newSViv(SYSINFO_EXTENDED));
-
SYSINFO_KEY_SET_HASH(key_uptime);
SYSINFO_KEY_SET_HASH(key_load1);
SYSINFO_KEY_SET_HASH(key_load5);
SYSINFO_KEY_SET_HASH(key_load15);
SYSINFO_KEY_SET_HASH(key_totalram);
SYSINFO_KEY_SET_HASH(key_freeram);
SYSINFO_KEY_SET_HASH(key_sharedram);
SYSINFO_KEY_SET_HASH(key_bufferram);
SYSINFO_KEY_SET_HASH(key_totalswap);
SYSINFO_KEY_SET_HASH(key_freeswap);
SYSINFO_KEY_SET_HASH(key_procs);
-#if SYSINFO_EXTENDED
SYSINFO_KEY_SET_HASH(key_totalhigh);
SYSINFO_KEY_SET_HASH(key_freehigh);
SYSINFO_KEY_SET_HASH(key_mem_unit);
-#endif /* SYSINFO_EXTENDED */
+ stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, TRUE);
+ newCONSTSUB(stash, "LS_HAS_EXTENDED", newSViv(LS_HAS_EXTENDED));
+
LS_KEY_DEFINE(uptime);
LS_KEY_DEFINE(load1);
LS_KEY_DEFINE(load5);
LS_KEY_DEFINE(load15);
LS_KEY_DEFINE(totalram);
LS_KEY_DEFINE(freeram);
LS_KEY_DEFINE(sharedram);
LS_KEY_DEFINE(bufferram);
LS_KEY_DEFINE(totalswap);
LS_KEY_DEFINE(freeswap);
LS_KEY_DEFINE(procs);
+#if LS_HAS_EXTENDED
LS_KEY_DEFINE(totalhigh);
LS_KEY_DEFINE(freehigh);
LS_KEY_DEFINE(mem_unit);
+#endif /* LS_HAS_EXTENDED */
 }
 
-SV *
-sysinfo()
+SV *sysinfo()
+PROTOTYPE:
 PREINIT:
  struct sysinfo si;
  NV l;
- HV *h;
+ HV *hv;
 CODE:
- if (sysinfo(&si) == -1) {
-  XSRETURN_UNDEF;
- }
+ if (sysinfo(&si) == -1) XSRETURN_UNDEF;
 
- h = newHV(); /* mortalized in RETVAL */
+ hv = newHV();
 
SYSINFO_KEY_STORE(h, key_uptime,    newSViv(si.uptime));
LS_KEY_STORE(hv, uptime,    newSViv(si.uptime));
 
  l = ((NV) si.loads[0]) / ((NV) (((U32) 1) << ((U32) SI_LOAD_SHIFT)));
SYSINFO_KEY_STORE(h, key_load1,     newSVnv(l));
LS_KEY_STORE(hv, load1,     newSVnv(l));
  l = ((NV) si.loads[1]) / ((NV) (((U32) 1) << ((U32) SI_LOAD_SHIFT)));
SYSINFO_KEY_STORE(h, key_load5,     newSVnv(l));
LS_KEY_STORE(hv, load5,     newSVnv(l));
  l = ((NV) si.loads[2]) / ((NV) (((U32) 1) << ((U32) SI_LOAD_SHIFT)));
SYSINFO_KEY_STORE(h, key_load15,    newSVnv(l));
-
SYSINFO_KEY_STORE(h, key_totalram,  newSVuv(si.totalram));
SYSINFO_KEY_STORE(h, key_freeram,   newSVuv(si.freeram));
SYSINFO_KEY_STORE(h, key_sharedram, newSVuv(si.sharedram));
SYSINFO_KEY_STORE(h, key_bufferram, newSVuv(si.bufferram));
SYSINFO_KEY_STORE(h, key_totalswap, newSVuv(si.totalswap));
SYSINFO_KEY_STORE(h, key_freeswap,  newSVuv(si.freeswap));
SYSINFO_KEY_STORE(h, key_procs,     newSVuv(si.procs));
-#if SYSINFO_EXTENDED
SYSINFO_KEY_STORE(h, key_totalhigh, newSVuv(si.totalhigh));
SYSINFO_KEY_STORE(h, key_freehigh,  newSVuv(si.freehigh));
SYSINFO_KEY_STORE(h, key_mem_unit,  newSVuv(si.mem_unit));
-#endif /* SYSINFO_EXTENDED */
-
- RETVAL = newRV_noinc((SV *) h);
LS_KEY_STORE(hv, load15,    newSVnv(l));
+
LS_KEY_STORE(hv, totalram,  newSVuv(si.totalram));
LS_KEY_STORE(hv, freeram,   newSVuv(si.freeram));
LS_KEY_STORE(hv, sharedram, newSVuv(si.sharedram));
LS_KEY_STORE(hv, bufferram, newSVuv(si.bufferram));
LS_KEY_STORE(hv, totalswap, newSVuv(si.totalswap));
LS_KEY_STORE(hv, freeswap,  newSVuv(si.freeswap));
LS_KEY_STORE(hv, procs,     newSVuv(si.procs));
+#if LS_HAS_EXTENDED
LS_KEY_STORE(hv, totalhigh, newSVuv(si.totalhigh));
LS_KEY_STORE(hv, freehigh,  newSVuv(si.freehigh));
LS_KEY_STORE(hv, mem_unit,  newSVuv(si.mem_unit));
+#endif /* LS_HAS_EXTENDED */
+
+ RETVAL = newRV_noinc((SV *) hv);
 OUTPUT:
  RETVAL