summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaLyong Cho <walyong.cho@samsung.com>2016-11-11 04:38:06 (GMT)
committerWaLyong Cho <walyong.cho@samsung.com>2016-11-11 04:41:19 (GMT)
commit8f2e46db8af79b256dae28504270e968793bc8a8 (patch)
tree9ff072882a5a1a9c0c11d9269c8e35a67a959eba
parent35bf52f9d3823fad34a70c3c4fcbad9a50b8f8c1 (diff)
downloadlibsystem-8f2e46db8af79b256dae28504270e968793bc8a8.zip
libsystem-8f2e46db8af79b256dae28504270e968793bc8a8.tar.gz
libsystem-8f2e46db8af79b256dae28504270e968793bc8a8.tar.bz2
libsystem: proc: add proc_get_buddyinfo()
To get a zone info from /proc/buddyinfo, add new api proc_get_buddyinfo(). Change-Id: Id88cb14e9bec057b72a53820fde6a66955cd77a8 Signed-off-by: WaLyong Cho <walyong.cho@samsung.com>
-rw-r--r--src/libsystem/proc.c63
-rw-r--r--src/libsystem/proc.h67
2 files changed, 130 insertions, 0 deletions
diff --git a/src/libsystem/proc.c b/src/libsystem/proc.c
index d429cf3..6a3d3df 100644
--- a/src/libsystem/proc.c
+++ b/src/libsystem/proc.c
@@ -357,3 +357,66 @@ int proc_get_meminfo(struct meminfo *mi, enum meminfo_mask mask) {
return 0;
}
+
+void proc_buddyinfo_free(struct buddyinfo *bi) {
+ if (!bi)
+ return;
+
+ free(bi->zone);
+ free(bi);
+}
+
+int proc_get_buddyinfo(const char *zone, struct buddyinfo **bi) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char buf[LINE_MAX];
+
+ assert(zone);
+ assert(bi);
+
+ f = fopen("/proc/buddyinfo", "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ _cleanup_buddyinfo_free_ struct buddyinfo *b = NULL;
+ int n;
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ if (ferror(f))
+ return -errno;
+
+ break;
+ }
+
+ b = new0(struct buddyinfo, 1);
+ if (!b)
+ return -ENOMEM;
+
+ n = sscanf(buf, "Node %d, zone %m[^ ] %d %d %d %d %d %d %d %d %d %d %d",
+ &b->node,
+ &b->zone,
+ &b->page[PAGE_4K],
+ &b->page[PAGE_8K],
+ &b->page[PAGE_16K],
+ &b->page[PAGE_32K],
+ &b->page[PAGE_64K],
+ &b->page[PAGE_128K],
+ &b->page[PAGE_256K],
+ &b->page[PAGE_512K],
+ &b->page[PAGE_1M],
+ &b->page[PAGE_2M],
+ &b->page[PAGE_4M]);
+ if (n != 13)
+ break;
+
+ if (!streq(zone, b->zone))
+ continue;
+
+ *bi = b;
+ b = NULL;
+
+ return 0;
+ }
+
+ return -ENODATA;
+}
diff --git a/src/libsystem/proc.h b/src/libsystem/proc.h
index 935db2d..995cd00 100644
--- a/src/libsystem/proc.h
+++ b/src/libsystem/proc.h
@@ -362,6 +362,73 @@ enum meminfo_id meminfo_string_to_id(const char *str);
int proc_get_meminfo(struct meminfo *mi, enum meminfo_mask mask);
/**
+ * /proc/buddyinfo page index
+ */
+enum {
+ PAGE_4K = 0,
+ PAGE_8K,
+ PAGE_16K,
+ PAGE_32K,
+ PAGE_64K,
+ PAGE_128K,
+ PAGE_256K,
+ PAGE_512K,
+ PAGE_1M,
+ PAGE_2M,
+ PAGE_4M,
+ PAGE_MAX,
+};
+
+/**
+ * A zone buddy info
+ */
+struct buddyinfo {
+ /**
+ * Zone name
+ */
+ char *zone;
+ /**
+ * Node number
+ */
+ int node;
+ /**
+ * Each pages size
+ */
+ int page[PAGE_MAX];
+};
+
+/**
+ * @brief free struct buddyinfo
+ *
+ * @param bi a buddyinfo
+ */
+void proc_buddyinfo_free(struct buddyinfo *bi);
+
+static inline void buddyinfo_freep(struct buddyinfo **bi)
+{
+ proc_buddyinfo_free(*bi);
+}
+
+/**
+ * Declare struct buddyinfo with cleanup attribute. Allocated struct
+ * buddyinfo is destroyed on going out the scope.
+ */
+#define _cleanup_buddyinfo_free_ _cleanup_(buddyinfo_freep)
+
+/**
+ * @brief Parse a zone in /proc/buddyinfo
+ *
+ * @param zone A zone to parse such like "Normal"
+ *
+ * @param bi Allocated and parsed buddyinfo for given zone. This value
+ * has to be destroyed by caller. #_cleanup_buddyinfo_free_ is useful
+ * to make autofree this value.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int proc_get_buddyinfo(const char *zone, struct buddyinfo **bi);
+
+/**
* @}
*/