Sysinfo(): Difference between revisions
(Created page with "== Overview == sysinfo() 함수 내용 설명 == Structure == === Until Linux-2.3.16 === <source lang=c> struct sysinfo { long uptime; /* Seconds since boot *...") |
|||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Overview == | == Overview == | ||
sysinfo() 함수 내용 설명 | sysinfo() 함수 내용 설명. | ||
sysinfo()는 시스템 전체 정보를 확인할 수 있는 함수이다. 주변장치를 주 대상으로 하는 sysfs() 와는 달리, sysinfo() 는 커널이 주 대상이다. | |||
== Synopsis == | |||
<source lang=c> | |||
#include <sys/sysinfo.h> | |||
int sysinfo(struct sysinfo *info); | |||
</source> | |||
== Structure == | == Structure == | ||
Line 46: | Line 55: | ||
전체 쓰레드 갯수는 아래의 명령어로 확인할 수 있다. | 전체 쓰레드 갯수는 아래의 명령어로 확인할 수 있다. | ||
< | <source lang=bash> | ||
$ grep -s '^Threads' /proc/[0-9]*/status | awk '{ sum += $2; } END { print sum; }' | $ grep -s '^Threads' /proc/[0-9]*/status | awk '{ sum += $2; } END { print sum; }' | ||
</ | </source> | ||
=== Implement === | |||
왜 sysinfo() 의 procs 가 쓰레드 갯수를 나타내는지는 sysinfo() 를 어떻게 구현했는지를 살펴보면 된다. 간단하게 procs가 nr_threads 를 참조하기 때문이다. | |||
<source lang=c> | |||
/** | |||
* do_sysinfo - fill in sysinfo struct | |||
* @info: pointer to buffer to fill | |||
*/ | |||
static int do_sysinfo(struct sysinfo *info) | |||
{ | |||
unsigned long mem_total, sav_total; | |||
unsigned int mem_unit, bitcount; | |||
struct timespec tp; | |||
memset(info, 0, sizeof(struct sysinfo)); | |||
get_monotonic_boottime(&tp); | |||
info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | |||
get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); | |||
info->procs = nr_threads; | |||
si_meminfo(info); | |||
si_swapinfo(info); | |||
/* | |||
* If the sum of all the available memory (i.e. ram + swap) | |||
* is less than can be stored in a 32 bit unsigned long then | |||
* we can be binary compatible with 2.2.x kernels. If not, | |||
* well, in that case 2.2.x was broken anyways... | |||
* | |||
* -Erik Andersen <andersee@debian.org> | |||
*/ | |||
mem_total = info->totalram + info->totalswap; | |||
if (mem_total < info->totalram || mem_total < info->totalswap) | |||
goto out; | |||
bitcount = 0; | |||
mem_unit = info->mem_unit; | |||
while (mem_unit > 1) { | |||
bitcount++; | |||
mem_unit >>= 1; | |||
sav_total = mem_total; | |||
mem_total <<= 1; | |||
if (mem_total < sav_total) | |||
goto out; | |||
} | |||
/* | |||
* If mem_total did not overflow, multiply all memory values by | |||
* info->mem_unit and set it to 1. This leaves things compatible | |||
* with 2.2.x, and also retains compatibility with earlier 2.4.x | |||
* kernels... | |||
*/ | |||
info->mem_unit = 1; | |||
info->totalram <<= bitcount; | |||
info->freeram <<= bitcount; | |||
info->sharedram <<= bitcount; | |||
info->bufferram <<= bitcount; | |||
info->totalswap <<= bitcount; | |||
info->freeswap <<= bitcount; | |||
info->totalhigh <<= bitcount; | |||
info->freehigh <<= bitcount; | |||
out: | |||
return 0; | |||
} | |||
</source> | |||
구 버전(아마도 2.3.16 버전 이전)의 경우는 nr_tasks 를 참조한다. | |||
<source lang=c> | |||
/* | |||
* linux/kernel/info.c | |||
* | |||
* Copyright (C) 1992 Darren Senn | |||
*/ | |||
/* This implements the sysinfo() system call */ | |||
#include <asm/segment.h> | |||
#include <linux/sched.h> | |||
#include <linux/string.h> | |||
#include <linux/unistd.h> | |||
#include <linux/types.h> | |||
#include <linux/mm.h> | |||
#include <linux/swap.h> | |||
asmlinkage int sys_sysinfo(struct sysinfo *info) | |||
{ | |||
int error; | |||
struct sysinfo val; | |||
error = verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo)); | |||
if (error) | |||
return error; | |||
memset((char *)&val, 0, sizeof(struct sysinfo)); | |||
val.uptime = jiffies / HZ; | |||
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); | |||
val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); | |||
val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); | |||
val.procs = nr_tasks-1; | |||
si_meminfo(&val); | |||
si_swapinfo(&val); | |||
memcpy_tofs(info, &val, sizeof(struct sysinfo)); | |||
return 0; | |||
} | |||
</source> | |||
== Sample == | == Sample == | ||
Line 81: | Line 205: | ||
} | } | ||
</source> | </source> | ||
== See also == | |||
* http://lxr.free-electrons.com/source/kernel/sys.c#L2293 - sys.c-4.5 | |||
* http://lxr.free-electrons.com/source/kernel/info.c?v=2.0.40 - sysinfo()-2.0.40 | |||
[[category:c]] | [[category:c]] |
Latest revision as of 10:48, 26 April 2016
Overview
sysinfo() 함수 내용 설명.
sysinfo()는 시스템 전체 정보를 확인할 수 있는 함수이다. 주변장치를 주 대상으로 하는 sysfs() 와는 달리, sysinfo() 는 커널이 주 대상이다.
Synopsis
<source lang=c>
- include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info); </source>
Structure
Until Linux-2.3.16
<source lang=c> struct sysinfo {
long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ char _f[22]; /* Pads structure to 64 bytes */
}; </source>
Since Linux-2.3.23
<source lang=c> struct sysinfo {
long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ unsigned long totalhigh; /* Total high memory size */ unsigned long freehigh; /* Available high memory size */ unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
}; </source>
Process count
sysinfo() 함수를 이용하면 현재 프로세스의 갯수 정보를 확인할 수 있다. <source lang=c> unsigned short procs; /* Number of current processes */ </source> 얼핏보면 단순한 프로세스의 갯수 정보일 것 같지만, 사실은 프로세스가 아니라 쓰레드 갯수로 표현해야 함이 맞다. 실제로 프로그램을 작성해서 돌려보면 sysinfo() 로 확인된 프로세스의 갯수와 ps/top 으로 확인된 프로세스 갯수가 서로 맞지 않는 것을 확인할 수 있다. 쓰레드 갯수로 확인하면 갯수가 맞는 것을 확인할 수 있다.
전체 쓰레드 갯수는 아래의 명령어로 확인할 수 있다. <source lang=bash>
$ grep -s '^Threads' /proc/[0-9]*/status | awk '{ sum += $2; } END { print sum; }'
</source>
Implement
왜 sysinfo() 의 procs 가 쓰레드 갯수를 나타내는지는 sysinfo() 를 어떻게 구현했는지를 살펴보면 된다. 간단하게 procs가 nr_threads 를 참조하기 때문이다. <source lang=c> /**
* do_sysinfo - fill in sysinfo struct * @info: pointer to buffer to fill */
static int do_sysinfo(struct sysinfo *info) {
unsigned long mem_total, sav_total; unsigned int mem_unit, bitcount; struct timespec tp;
memset(info, 0, sizeof(struct sysinfo));
get_monotonic_boottime(&tp); info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
info->procs = nr_threads;
si_meminfo(info); si_swapinfo(info);
/* * If the sum of all the available memory (i.e. ram + swap) * is less than can be stored in a 32 bit unsigned long then * we can be binary compatible with 2.2.x kernels. If not, * well, in that case 2.2.x was broken anyways... * * -Erik Andersen <andersee@debian.org> */
mem_total = info->totalram + info->totalswap; if (mem_total < info->totalram || mem_total < info->totalswap) goto out; bitcount = 0; mem_unit = info->mem_unit; while (mem_unit > 1) { bitcount++; mem_unit >>= 1; sav_total = mem_total; mem_total <<= 1; if (mem_total < sav_total) goto out; }
/* * If mem_total did not overflow, multiply all memory values by * info->mem_unit and set it to 1. This leaves things compatible * with 2.2.x, and also retains compatibility with earlier 2.4.x * kernels... */
info->mem_unit = 1; info->totalram <<= bitcount; info->freeram <<= bitcount; info->sharedram <<= bitcount; info->bufferram <<= bitcount; info->totalswap <<= bitcount; info->freeswap <<= bitcount; info->totalhigh <<= bitcount; info->freehigh <<= bitcount;
out:
return 0;
} </source>
구 버전(아마도 2.3.16 버전 이전)의 경우는 nr_tasks 를 참조한다. <source lang=c> /*
* linux/kernel/info.c * * Copyright (C) 1992 Darren Senn */
/* This implements the sysinfo() system call */
- include <asm/segment.h>
- include <linux/sched.h>
- include <linux/string.h>
- include <linux/unistd.h>
- include <linux/types.h>
- include <linux/mm.h>
- include <linux/swap.h>
asmlinkage int sys_sysinfo(struct sysinfo *info) {
int error; struct sysinfo val;
error = verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo)); if (error) return error; memset((char *)&val, 0, sizeof(struct sysinfo));
val.uptime = jiffies / HZ;
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
val.procs = nr_tasks-1;
si_meminfo(&val); si_swapinfo(&val);
memcpy_tofs(info, &val, sizeof(struct sysinfo)); return 0;
} </source>
Sample
<source lang=c>
- include <stdio.h>
- include <sys/sysinfo.h>
int main(int argc, char** argv) {
struct sysinfo info; sysinfo(&info); printf("uptime[%ld]\n", info.uptime); printf("load_1[%lu]\n", info.loads[0]); printf("load_5[%lu]\n", info.loads[1]); printf("load_15[%lu]\n", info.loads[2]); printf("total ram[%lu]\n", info.totalram); printf("free ram[%lu]\n", info.freeram); printf("shared ram[%lu]\n", info.sharedram); printf("buffer ram[%lu]\n", info.bufferram); printf("total swap[%lu]\n", info.totalswap); printf("free swap[%lu]\n", info.freeswap); printf("procs[%d]\n", info.procs); printf("total high[%lu]\n", info.totalhigh); printf("free high[%lu]\n", info.freehigh); printf("free high[%lu]\n", info.freehigh); printf("mem unit[%u]\n", info.mem_unit); return 0;
} </source>
See also
- http://lxr.free-electrons.com/source/kernel/sys.c#L2293 - sys.c-4.5
- http://lxr.free-electrons.com/source/kernel/info.c?v=2.0.40 - sysinfo()-2.0.40