From: WaLyong Cho Date: Fri, 11 Nov 2016 04:38:06 +0000 (+0900) Subject: libsystem: proc: add proc_get_buddyinfo() X-Git-Tag: submit/tizen/20180322.062032~2^2~2^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8f2e46db8af79b256dae28504270e968793bc8a8;p=platform%2Fcore%2Fsystem%2Flibsystem.git 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 --- 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 @@ -361,6 +361,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); + /** * @} */