⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slab.c

📁 linux下获取一些环境信息的代码
💻 C
字号:
/*  * slab.c - slab related functions for libproc * * Chris Rivera <cmrivera@ufl.edu> * Robert Love <rml@tech9.net> * * This program is licensed under the GNU Library General Public License, v2 * * Copyright (C) 2003 Chris Rivera * Copyright 2004, Albert Cahalan */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <limits.h>#include <ctype.h>#include "slab.h"#include "procps.h"#define SLABINFO_LINE_LEN	2048#define SLABINFO_VER_LEN	100#define SLABINFO_FILE		"/proc/slabinfo"static struct slab_info *free_index;/* * get_slabnode - allocate slab_info structures using a free list * * In the fast path, we simply return a node off the free list.  In the slow * list, we malloc() a new node.  The free list is never automatically reaped, * both for simplicity and because the number of slab caches is fairly * constant. */static struct slab_info *get_slabnode(void){	struct slab_info *node;	if (free_index) {		node = free_index;		free_index = free_index->next;	} else {		node = malloc(sizeof(struct slab_info));		if (!node)			perror("malloc");	}	return node;}/* * slab_badname_detect - return true if current slab was declared with *                       whitespaces for instance  *			 FIXME :Other cases ? */static int slab_badname_detect(const char *restrict buffer){	int numberarea=0;	while (*buffer){		if((*buffer)==' ')			numberarea=1;		if(isalpha(*buffer)&&numberarea)				return 1;		buffer++;		}	return 0;}/* * put_slabinfo - return all allocated nodes to the free list */void put_slabinfo(struct slab_info *head){	free_index = head;}/* * free_slabinfo - deallocate the memory associated with each node in the * slab_info linked list */void free_slabinfo(struct slab_info *list){	while (list) {		struct slab_info *temp = list->next;		free(list);		list = temp;	}}// parse_slabinfo20 - actual parse routine for slabinfo 2.x (2.6 kernels)// Note: difference between 2.0 and 2.1 is in the ": globalstat" part where version 2.1 // has extra column <nodeallocs>. We don't use ": globalstat" part in both versions.//// Formats (we don't use "statistics" extensions)////  slabinfo - version: 2.1//  # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> \//  : tunables <batchcount> <limit> <sharedfactor> \//  : slabdata <active_slabs> <num_slabs> <sharedavail>////  slabinfo - version: 2.1 (statistics)//  # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> \//  : tunables <batchcount> <limit> <sharedfactor> \//  : slabdata <active_slabs> <num_slabs> <sharedavail> \//  : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <freelimit> <nodeallocs> \//  : cpustat <allochit> <allocmiss> <freehit> <freemiss>//             //  slabinfo - version: 2.0//  # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> \//  : tunables <batchcount> <limit> <sharedfactor> \//  : slabdata <active_slabs> <num_slabs> <sharedavail>////  slabinfo - version: 2.0 (statistics)//  # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> \//  : tunables <batchcount> <limit> <sharedfactor> \//  : slabdata <active_slabs> <num_slabs> <sharedavail> \//  : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <freelimit> \//  : cpustat <allochit> <allocmiss> <freehit> <freemiss>static int parse_slabinfo20(struct slab_info **list, struct slab_stat *stats,				FILE *f){	struct slab_info *curr = NULL, *prev = NULL;	char buffer[SLABINFO_LINE_LEN];	int entries = 0;	int page_size = getpagesize();	stats->min_obj_size = INT_MAX;	stats->max_obj_size = 0;	while (fgets(buffer, SLABINFO_LINE_LEN, f)) {		int assigned;		if (buffer[0] == '#')			continue;			curr = get_slabnode();		if (!curr)			break;		if (entries++ == 0)			*list = curr;		else			prev->next = curr;		assigned = sscanf(buffer, "%" STRINGIFY(SLAB_INFO_NAME_LEN)				"s %d %d %d %d %d : tunables %*d %*d %*d : \				slabdata %d %d %*d", curr->name, 				&curr->nr_active_objs, &curr->nr_objs, 				&curr->obj_size, &curr->objs_per_slab,				&curr->pages_per_slab, &curr->nr_active_slabs,				&curr->nr_slabs);		if (assigned < 8) {			fprintf(stderr, "unrecognizable data in slabinfo!\n");			curr = NULL;			break;		}		if (curr->obj_size < stats->min_obj_size)			stats->min_obj_size = curr->obj_size;		if (curr->obj_size > stats->max_obj_size)			stats->max_obj_size = curr->obj_size;		curr->cache_size = (unsigned long)curr->nr_slabs * curr->pages_per_slab * page_size;		if (curr->nr_objs) {			curr->use = 100 * curr->nr_active_objs / curr->nr_objs;			stats->nr_active_caches++;		} else			curr->use = 0;		stats->nr_objs += curr->nr_objs;		stats->nr_active_objs += curr->nr_active_objs;		stats->total_size += (unsigned long)curr->nr_objs * curr->obj_size;		stats->active_size += (unsigned long)curr->nr_active_objs * curr->obj_size;		stats->nr_pages += curr->nr_slabs * curr->pages_per_slab;		stats->nr_slabs += curr->nr_slabs;		stats->nr_active_slabs += curr->nr_active_slabs;		prev = curr;	}	if (!curr) {		fprintf(stderr, "\rerror reading slabinfo!\n");		return 1;	}	curr->next = NULL;	stats->nr_caches = entries;	if (stats->nr_objs)		stats->avg_obj_size = stats->total_size / stats->nr_objs;	return 0;}/* * parse_slabinfo11 - actual parsing routine for slabinfo 1.1 (2.4 kernels) */static int parse_slabinfo11(struct slab_info **list, struct slab_stat *stats,				FILE *f){	struct slab_info *curr = NULL, *prev = NULL;	char buffer[SLABINFO_LINE_LEN];	int entries = 0;	int page_size = getpagesize();	stats->min_obj_size = INT_MAX;	stats->max_obj_size = 0;	while (fgets(buffer, SLABINFO_LINE_LEN, f)) {		int assigned;		curr = get_slabnode();		if (!curr)			break;		if (entries++ == 0)			*list = curr;		else			prev->next = curr;		assigned = sscanf(buffer, "%" STRINGIFY(SLAB_INFO_NAME_LEN)				"s %d %d %d %d %d %d",				curr->name, &curr->nr_active_objs,				&curr->nr_objs, &curr->obj_size,				&curr->nr_active_slabs, &curr->nr_slabs,				&curr->pages_per_slab);		if (assigned < 6) {			fprintf(stderr, "unrecognizable data in  your slabinfo version 1.1\n\r");			if(slab_badname_detect(buffer))				fprintf(stderr, "Found an error in cache name at line %s\n", buffer); 			curr = NULL;			break;		}		if (curr->obj_size < stats->min_obj_size)			stats->min_obj_size = curr->obj_size;		if (curr->obj_size > stats->max_obj_size)			stats->max_obj_size = curr->obj_size;		curr->cache_size = (unsigned long)curr->nr_slabs * curr->pages_per_slab * page_size;		if (curr->nr_objs) {			curr->use = 100 * curr->nr_active_objs / curr->nr_objs;			stats->nr_active_caches++;		} else			curr->use = 0;		if (curr->obj_size)			curr->objs_per_slab = curr->pages_per_slab *					page_size / curr->obj_size;				stats->nr_objs += curr->nr_objs;		stats->nr_active_objs += curr->nr_active_objs;		stats->total_size += (unsigned long)curr->nr_objs * curr->obj_size;		stats->active_size += (unsigned long)curr->nr_active_objs * curr->obj_size;		stats->nr_pages += curr->nr_slabs * curr->pages_per_slab;		stats->nr_slabs += curr->nr_slabs;		stats->nr_active_slabs += curr->nr_active_slabs;		prev = curr;	}	if (!curr) {		fprintf(stderr, "\rerror reading slabinfo!\n");		return 1;	}	curr->next = NULL;	stats->nr_caches = entries;	if (stats->nr_objs)		stats->avg_obj_size = stats->total_size / stats->nr_objs;	return 0;}/* * parse_slabinfo10 - actual parsing routine for slabinfo 1.0 (2.2 kernels) * * Not yet implemented.  Please feel free. */static int parse_slabinfo10(struct slab_info **list, struct slab_stat *stats,				FILE *f){	(void) list, (void) stats, (void) f;	fprintf(stderr, "slabinfo version 1.0 not yet supported\n");	return 1;}/* * slabinfo - parse the system's slabinfo and fill out both a linked list of * slab_info structures and the slab_stat structure * * The function returns zero on success, in which case 'list' and 'stats' are * valid.  Nonzero is returned on failure and the state of 'list' and 'stats' * are undefined. */int get_slabinfo(struct slab_info **list, struct slab_stat *stats){	FILE *slabfile;	char buffer[SLABINFO_VER_LEN];	int major, minor, ret = 0;	slabfile = fopen(SLABINFO_FILE, "r");	if (!slabfile) {		perror("fopen " SLABINFO_FILE);		return 1;	}	if (!fgets(buffer, SLABINFO_VER_LEN, slabfile)) {		fprintf(stderr, "cannot read from slabinfo\n");		return 1;	}	if (sscanf(buffer, "slabinfo - version: %d.%d", &major, &minor) != 2) {		fprintf(stderr, "not the good old slabinfo we know\n");		return 1;	}	if (major == 2)		ret = parse_slabinfo20(list, stats, slabfile);	else if (major == 1 && minor == 1)		ret = parse_slabinfo11(list, stats, slabfile);	else if (major == 1 && minor == 0)		ret = parse_slabinfo10(list, stats, slabfile);	else {		fprintf(stderr, "unrecognizable slabinfo version\n");		return 1;	}	fclose(slabfile);	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -