示例#1
0
文件: psi.c 项目: AlexShiLucky/linux
int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res)
{
	int full;

	if (static_branch_likely(&psi_disabled))
		return -EOPNOTSUPP;

	update_stats(group);

	for (full = 0; full < 2 - (res == PSI_CPU); full++) {
		unsigned long avg[3];
		u64 total;
		int w;

		for (w = 0; w < 3; w++)
			avg[w] = group->avg[res * 2 + full][w];
		total = div_u64(group->total[res * 2 + full], NSEC_PER_USEC);

		seq_printf(m, "%s avg10=%lu.%02lu avg60=%lu.%02lu avg300=%lu.%02lu total=%llu\n",
			   full ? "full" : "some",
			   LOAD_INT(avg[0]), LOAD_FRAC(avg[0]),
			   LOAD_INT(avg[1]), LOAD_FRAC(avg[1]),
			   LOAD_INT(avg[2]), LOAD_FRAC(avg[2]),
			   total);
	}

	return 0;
}
示例#2
0
static int loadavg_proc_show(struct seq_file *m, void *v)
{
	unsigned long avnrun[3], nr_runnable = 0;
	struct cpumask cpus_allowed;
	int i;

	rcu_read_lock();
	if (task_in_nonroot_cpuacct(current) &&
		in_noninit_pid_ns(current->nsproxy->pid_ns)) {

		get_avenrun_from_tsk(current, avnrun, FIXED_1/200, 0);

		cpumask_copy(&cpus_allowed, cpu_possible_mask);
		if (task_subsys_state(current, cpuset_subsys_id)) {
			memset(&cpus_allowed, 0, sizeof(cpus_allowed));
			get_tsk_cpu_allowed(current, &cpus_allowed);
		}

		for_each_cpu_and(i, cpu_possible_mask, &cpus_allowed)
			nr_runnable += task_ca_running(current, i);

	} else {
		get_avenrun(avnrun, FIXED_1/200, 0);
		nr_runnable = nr_running();
	}
	rcu_read_unlock();

	seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
		LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
		LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
		LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
		nr_running(), nr_threads,
		task_active_pid_ns(current)->last_pid);
	return 0;
}
示例#3
0
int uptime_main(int argc, char **argv)
{
	int updays, uphours, upminutes;
	struct sysinfo info;
	struct tm *current_time;
	time_t current_secs;

	time(&current_secs);
	current_time = localtime(&current_secs);

	sysinfo(&info);

	printf(" %02d:%02d:%02d up ",
			current_time->tm_hour, current_time->tm_min, current_time->tm_sec);
	updays = (int) info.uptime / (60*60*24);
	if (updays)
		printf("%d day%s, ", updays, (updays != 1) ? "s" : "");
	upminutes = (int) info.uptime / 60;
	uphours = (upminutes / 60) % 24;
	upminutes %= 60;
	if (uphours)
		printf("%2d:%02d, ", uphours, upminutes);
	else
		printf("%d min, ", upminutes);

	printf("load average: %ld.%02ld, %ld.%02ld, %ld.%02ld\n",
			LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]),
			LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]),
			LOAD_INT(info.loads[2]), LOAD_FRAC(info.loads[2]));

	return EXIT_SUCCESS;
}
示例#4
0
int main(int argc,char **argv) {
	struct sysinfo si;
        sysinfo(&si);
	printf("%ld.%02ld,%ld.%02ld,%ld.%02ld\n",
                        LOAD_INT(si.loads[0]), LOAD_FRAC(si.loads[0]),
                        LOAD_INT(si.loads[1]), LOAD_FRAC(si.loads[1]),
                        LOAD_INT(si.loads[2]), LOAD_FRAC(si.loads[2]));
	exit(0);
}
示例#5
0
static int get_loadavg(char * buffer)
{
	int a, b, c;

	a = avenrun[0] + (FIXED_1/200);
	b = avenrun[1] + (FIXED_1/200);
	c = avenrun[2] + (FIXED_1/200);
	return sprintf(buffer,"%d.%02d %d.%02d %d.%02d\n",
		LOAD_INT(a), LOAD_FRAC(a),
		LOAD_INT(b), LOAD_FRAC(b),
		LOAD_INT(c), LOAD_FRAC(c));
}
示例#6
0
static int get_loadavg(char * buffer)
{
    int a, b, c;

    a = avenrun[0] + (FIXED_1/200);
    b = avenrun[1] + (FIXED_1/200);
    c = avenrun[2] + (FIXED_1/200);
    return sprintf(buffer,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
                   LOAD_INT(a), LOAD_FRAC(a),
                   LOAD_INT(b), LOAD_FRAC(b),
                   LOAD_INT(c), LOAD_FRAC(c),
                   nr_running, nr_tasks, last_pid);
}
static int loadavg_proc_show(struct seq_file *m, void *v)
{
	unsigned long avnrun[3];

	get_avenrun(avnrun, FIXED_1/200, 0);

	seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
		LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
		LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
		LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
		nr_running(), nr_threads,
		task_active_pid_ns(current)->last_pid);
	return 0;
}
示例#8
0
static int get_loadavg(void)
{
	unsigned long this = this_cpu_load();


	return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10;
}
示例#9
0
static int loadavg_read_proc(char *page, char **start, off_t off,
				 int count, int *eof, void *data)
{
	int a, b, c;
	int len;

	a = avenrun[0] + (FIXED_1/200);
	b = avenrun[1] + (FIXED_1/200);
	c = avenrun[2] + (FIXED_1/200);
	len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
		LOAD_INT(a), LOAD_FRAC(a),
		LOAD_INT(b), LOAD_FRAC(b),
		LOAD_INT(c), LOAD_FRAC(c),
		nr_running, nr_threads, last_pid);
	return proc_calc_metrics(page, start, off, count, eof, len);
}
示例#10
0
static unsigned long determine_loadavg(void)
{
	unsigned long  avg = 0;
	unsigned long avnrun[3];

	get_avenrun(avnrun, FIXED_1 / 200, 0);
	avg += (LOAD_INT(avnrun[0]) * 100) + (LOAD_FRAC(avnrun[0]) % 100);

	return avg;
}
示例#11
0
static int loadavg_proc_show(struct seq_file *m, void *v)
{
	int a, b, c;
	unsigned long seq;

	do {
		seq = read_seqbegin(&xtime_lock);
		a = avenrun[0] + (FIXED_1/200);
		b = avenrun[1] + (FIXED_1/200);
		c = avenrun[2] + (FIXED_1/200);
	} while (read_seqretry(&xtime_lock, seq));

	seq_printf(m, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
		LOAD_INT(a), LOAD_FRAC(a),
		LOAD_INT(b), LOAD_FRAC(b),
		LOAD_INT(c), LOAD_FRAC(c),
		nr_running(), nr_threads,
		task_active_pid_ns(current)->last_pid);
	return 0;
}
示例#12
0
static ssize_t proto_write_periodic(unsigned long data)
{
    //Size of buffer for dummy data
    int count = 5;

    struct usb_skel *dev;
    int retval = 0;
    struct urb *urb = NULL;
    char *buf = NULL;

    dev = (struct usb_skel *) data;

    printk("Inside Timer Routine count-> %d\n",step++);
    printk("Inside Timer idProduct %02X, idVendor %02X\n",dev->udev->descriptor.idProduct, dev->udev->descriptor.idVendor);
    struct sysinfo kk;
    si_meminfo(&kk);
    //sys_sysinfo(&kk);
    
    kk.uptime=jiffies/HZ;
    int days=kk.uptime/86400;
    int hours=kk.uptime/3600 - days*24;
    int mins=(kk.uptime/60) - (days*1440) - (hours*60);

	printk(KERN_INFO "Days since boot: %d\n", (days));
    printk(KERN_INFO "Hours since boot: %d\n", (hours));
    printk(KERN_INFO "Mins since boot: %d\n", (mins));
    printk(KERN_INFO "Seconds since boot: %d\n", (kk.uptime));
    printk(KERN_INFO "CPU load: %d\n", (kk.loads[0]));
    printk(KERN_INFO "CPU load: %d\n", (avenrun[0] << (SI_LOAD_SHIFT - FSHIFT)));
    printk(KERN_INFO "CPU load: %d\n", (avenrun[1] << (SI_LOAD_SHIFT - FSHIFT)));
    printk(KERN_INFO "CPU load: %d\n", (avenrun[2] << (SI_LOAD_SHIFT - FSHIFT)));
    int a, b, c;
    a = avenrun[0] + (FIXED_1/200);
    b = avenrun[1] + (FIXED_1/200);
    c = avenrun[2] + (FIXED_1/200);
    printk(KERN_INFO "%d.%02d %d.%02d %d.%02d\n", LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c));
    printk(KERN_INFO "Total usable main memory size: %lu\n", (kk.totalram)*(unsigned long long)kk.mem_unit/1048576);
    printk(KERN_INFO "Available memory size: %lu\n", (kk.freeram)*(unsigned long long)kk.mem_unit/1048576);
    printk(KERN_INFO "Number of current processes: %u\n", (kk.procs));
	
	



    /* verify that we actually have some data to write */
    if (count == 0)
            goto exit;

    /* create a urb, and a buffer for it, and copy the data to the urb */
    urb = usb_alloc_urb(0, GFP_KERNEL);
    if (!urb) {
            retval = -ENOMEM;
            goto error;
    }

    buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
    if (!buf) {
            retval = -ENOMEM;
            goto error;
    }

    //Dummy data
    printk("load %d\n",LOAD_INT(a)*100+LOAD_FRAC(a));
    //(kk.totalram)*((unsigned long long)kk.mem_unit/1048576)
    printk("mem %d\n",((kk.totalram)*(unsigned long long)kk.mem_unit/1048576));
    printk("mem %d\n",(100-((kk.freeram)*(unsigned long long)kk.mem_unit/1048576)*100/((kk.totalram)*(unsigned long long)kk.mem_unit/1048576)));
    buf[0]='R';
    buf[1]='a';//(int16_t)(avenrun[0] << (SI_LOAD_SHIFT - FSHIFT)*100);
    buf[2]=(char)(LOAD_INT(a)*100+LOAD_FRAC(a));
    buf[3]=(char)(100-((kk.freeram)*(unsigned long long)kk.mem_unit/1048576)*100/((kk.totalram)*(unsigned long long)kk.mem_unit/1048576));//hours;
    buf[4]='l';
    printk("WRITE LOKA: buffer:\n");
    int i;
    for (i= 0; i < 5; ++i)
    {
    	printk("%d - %c (%d)\n",buf[i],buf[i],i);
    }

    /* initialize the urb properly */
    usb_fill_bulk_urb(urb, dev->udev,
                      usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
                      buf, count, proto_write_bulk_callback, dev);
    urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

    /* send the data out the bulk port */
    retval = usb_submit_urb(urb, GFP_KERNEL);
    if (retval) {
            pr_err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
            goto error;
    }

    /* release our reference to this urb, the USB core will eventually free it entirely */
    usb_free_urb(urb);

exit:
    mod_timer(&timer_write_periodic, jiffies + HZ); /* restarting timer */
    return count;

error:
    usb_free_coherent(dev->udev, count, buf, urb->transfer_dma);
    usb_free_urb(urb);
    kfree(buf);
    mod_timer(&timer_write_periodic, jiffies + HZ); /* restarting timer */
    return retval;
}
示例#13
0
文件: menu.c 项目: CCNITSilchar/linux
static inline int get_loadavg(unsigned long load)
{
	return LOAD_INT(load) * 10 + LOAD_FRAC(load) / 10;
}
void CDBoxInfoWidget::paint()
{
	const int headSize = 5;
	const char *head[headSize] = {"Filesystem", "Size", "Used", "Available", "Use%"};
	int fontWidth = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getWidth();
	int sizeOffset = fontWidth * 7;//9999.99M
	int percOffset = fontWidth * 3 ;//100%
	int nameOffset = fontWidth * 9;//WWWwwwwwww
	int offsetw = nameOffset+ (sizeOffset+10)*3 +10+percOffset+10;
	offsetw += 20;
	width = offsetw + 10 + 120;
	height = hheight + 6 * mheight;

	struct statfs s;
	FILE *          mountFile;
	struct mntent * mnt;

	/* this is lame, as it duplicates code. OTOH, it is small and fast enough...
	   The algorithm is exactly the same as below in the display routine */
	if ((mountFile = setmntent("/proc/mounts", "r")) == NULL) {
		perror("/proc/mounts");
	} else {
		while ((mnt = getmntent(mountFile)) != NULL) {
			if (::statfs(mnt->mnt_dir, &s) == 0) {
				switch (s.f_type)	/* f_type is long */
				{
				case 0xEF53L:		/*EXT2 & EXT3*/
				case 0x6969L:		/*NFS*/
				case 0xFF534D42L:	/*CIFS*/
				case 0x517BL:		/*SMB*/
				case 0x52654973L:	/*REISERFS*/
				case 0x65735546L:	/*fuse for ntfs*/
				case 0x58465342L:	/*xfs*/
				case 0x4d44L:		/*msdos*/
					break;
				case 0x72b6L:		/*jffs2*/
					if (strcmp(mnt->mnt_fsname, "rootfs") == 0)
						continue;
					height += mheight;
					break;
				default:
					continue;
				}
				height += mheight;
			}
		}
		endmntent(mountFile);
	}

	width = w_max(width, 0);
	height = h_max(height, 0);
	x = getScreenStartX(width);
	y = getScreenStartY(height);

	fprintf(stderr, "CDBoxInfoWidget::CDBoxInfoWidget() x = %d, y = %d, width = %d height = %d\n", x, y, width, height);
	int ypos=y;
	int i = 0;
	frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP);
	frameBuffer->paintBoxRel(x, ypos+ hheight, width, height- hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM);

	ypos+= hheight + (mheight >>1);
	FILE* fd = fopen("/proc/cpuinfo", "rt");
	if (fd==NULL) {
		printf("error while opening proc-cpuinfo\n" );
	} else {
		char *buffer=NULL;
		size_t len = 0;
		ssize_t read;
		while ((read = getline(&buffer, &len, fd)) != -1) {
			if (!(strncmp(const_cast<char *>("Hardware"),buffer,8))) {
				char *t=rindex(buffer,'\n');
				if (t)
					*t='\0';

				std::string hw;
				char *p=rindex(buffer,':');
				if (p)
					hw=++p;
				hw+=" Info";
				g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10, y + hheight+1, width - 10, hw.c_str(), COL_MENUHEAD, 0, true); // UTF-8
				break;
			}
			i++;
			if (i > 2)
				continue;
			g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, buffer, COL_MENUCONTENT);
			ypos+= mheight;
		}
		fclose(fd);
		if (buffer)
			free(buffer);
	}
	char *ubuf=NULL, *sbuf=NULL;
	int buf_size=256;
	ubuf = new char[buf_size];
	sbuf = new char[buf_size];

	if (sbuf != NULL && ubuf != NULL) {
		int updays, uphours, upminutes;
		struct sysinfo info;
		struct tm *current_time;
		time_t current_secs;
		memset(sbuf, 0, 256);
		time(&current_secs);
		current_time = localtime(&current_secs);

		sysinfo(&info);

		snprintf( ubuf,buf_size, "%2d:%02d%s  up ",
			  current_time->tm_hour%12 ? current_time->tm_hour%12 : 12,
			  current_time->tm_min, current_time->tm_hour > 11 ? "pm" : "am");
		strcat(sbuf, ubuf);
		updays = (int) info.uptime / (60*60*24);
		if (updays) {
			snprintf(ubuf,buf_size, "%d day%s, ", updays, (updays != 1) ? "s" : "");
			strcat(sbuf, ubuf);
		}
		upminutes = (int) info.uptime / 60;
		uphours = (upminutes / 60) % 24;
		upminutes %= 60;
		if (uphours)
			snprintf(ubuf,buf_size,"%2d:%02d, ", uphours, upminutes);
		else
			snprintf(ubuf,buf_size,"%d min, ", upminutes);
		strcat(sbuf, ubuf);

		snprintf(ubuf,buf_size, "load: %ld.%02ld, %ld.%02ld, %ld.%02ld\n",
			 LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]),
			 LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]),
			 LOAD_INT(info.loads[2]), LOAD_FRAC(info.loads[2]));
		strcat(sbuf, ubuf);
		ypos+= mheight/2;
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, sbuf, COL_MENUCONTENT);
		ypos+= mheight;

		snprintf(ubuf,buf_size, "memory total %dKb, free %dKb", (int) info.totalram/1024, (int) info.freeram/1024);
		ypos+= mheight/2;
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, ubuf, COL_MENUCONTENT);
		ypos+= mheight;
		int headOffset=0;
		int mpOffset=0;
		bool rec_mp=false;
		if ((mountFile = setmntent("/proc/mounts", "r")) == 0 ) {
			perror("/proc/mounts");
		}
		else {
			float gb=0;
			char c=' ';
			while ((mnt = getmntent(mountFile)) != 0) {
				if (::statfs(mnt->mnt_dir, &s) == 0) {
					switch (s.f_type)
					{
					case (int) 0xEF53:      /*EXT2 & EXT3*/
					case (int) 0x6969:      /*NFS*/
					case (int) 0xFF534D42:  /*CIFS*/
					case (int) 0x517B:      /*SMB*/
					case (int) 0x52654973:  /*REISERFS*/
					case (int) 0x65735546:  /*fuse for ntfs*/
					case (int) 0x58465342:  /*xfs*/
					case (int) 0x4d44:      /*msdos*/
						gb = 1024.0*1024.0;
						c = 'G';
						break;
					case (int) 0x72b6:	/*jffs2*/
						if (strcmp(mnt->mnt_fsname, "rootfs") == 0)
							continue;
						// paint mount head
						for (int j = 0; j < headSize; j++) {
							switch (j)
							{
							case 0:
								headOffset = 10;
								break;
							case 1:
								headOffset = nameOffset + 20;
								break;
							case 2:
								headOffset = nameOffset + sizeOffset+10 +20;
								break;
							case 3:
								headOffset = nameOffset + (sizeOffset+10)*2+15;
								break;
							case 4:
								headOffset = nameOffset + (sizeOffset+10)*3+15;
								break;
							}
							g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ headOffset, ypos+ mheight, width - 10, head[j], COL_MENUCONTENTINACTIVE);
						}
						ypos+= mheight;

						gb = 1024.0;
						c = 'M';
						break;
					default:
						continue;
					}
					if ( s.f_blocks > 0 ) {
						long	blocks_used;
						long	blocks_percent_used;
						blocks_used = s.f_blocks - s.f_bfree;
						blocks_percent_used = (long)(blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
						//paint mountpoints
						for (int j = 0; j < headSize; j++) {
							switch (j)
							{
							case 0: {
								if (s.f_type != 0x72b6)
								{
									char *p1=NULL, *p2=NULL;
									p1=strchr(g_settings.network_nfs_recordingdir+1,'/') ;
									p2=strchr(mnt->mnt_dir+1,'/') ;
									if (p2) {
										if (strstr(p1,p2)) {

											rec_mp = true;
										}
									}
									else {
										if (strstr(g_settings.network_nfs_recordingdir,mnt->mnt_dir)) {
											rec_mp = true;
										}
									}
								}
								mpOffset = 10;
								snprintf(ubuf,buf_size,"%-10.10s",basename(mnt->mnt_fsname));
							}
							break;
							case 1:
								mpOffset = nameOffset + 10;
								snprintf(ubuf,buf_size,"%7.2f%c", (s.f_blocks * (s.f_bsize / 1024.0)) / gb, c);
								break;
							case 2:
								mpOffset = nameOffset+ (sizeOffset+10)*1+10;
								snprintf(ubuf,buf_size,"%7.2f%c", ((s.f_blocks - s.f_bfree)  * (s.f_bsize / 1024.0)) / gb, c);
								break;
							case 3:
								mpOffset = nameOffset+ (sizeOffset+10)*2+10;
								snprintf(ubuf,buf_size,"%7.2f%c", s.f_bavail * (s.f_bsize / 1024.0) / gb, c);
								break;
							case 4:
								mpOffset = nameOffset+ (sizeOffset+10)*3+10;
								snprintf(ubuf,buf_size,"%4ld%c", blocks_percent_used,'%');
								break;
							}
							g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + mpOffset, ypos+ mheight, width - 10, ubuf, rec_mp ? COL_MENUHEAD+2:COL_MENUCONTENT);
							rec_mp = false;
						}
						int pbw = width - offsetw - 10;
//fprintf(stderr, "width: %d offsetw: %d pbw: %d\n", width, offsetw, pbw);
						if (pbw > 8) /* smaller progressbar is not useful ;) */
						{
							CProgressBar pb(true, -1, -1, 30, 100, 70, true);
							pb.paintProgressBarDefault(x+offsetw, ypos+3, pbw, mheight-10, blocks_percent_used, 100);
						}
						ypos+= mheight;
					}
					i++;
				}
				if (ypos > y + height - mheight)	/* the screen is not high enough */
					break;				/* todo: scrolling? */
			}
			endmntent(mountFile);
		}
	}
	if (sbuf)
		delete[] sbuf;
	if (ubuf)
		delete[] ubuf;

}
示例#15
0
void CDBoxInfoWidget::paint()
{
	const int head_info_lines = 3;
	const char *head_info[head_info_lines] = {"Uptime", "Load average", "Current load"};

	height = hheight;
	height += mheight/2;	// space
	int cpuload_y0 = height;
	int head_info_ypos = height;
	height += mheight*head_info_lines;	// head info lines
	int cpuload_y1 = height;
	height += mheight/2;	// space

	int icon_w = 0, icon_h = 0;
	frameBuffer->getIconSize(NEUTRINO_ICON_REC, &icon_w, &icon_h);

#define MEMINFO_TOTAL 0
#define MEMINFO_USED 1
#define MEMINFO_FREE 2
#define MEMINFO_COLUMNS 3

#define MEMINFO_RAM 0
#define MEMINFO_SWAP 1
#define MEMINFO_ROWS 2
	unsigned long memstat[MEMINFO_ROWS][MEMINFO_COLUMNS] = { { 0, 0, 0 }, { 0, 0, 0 } }; // total, used, free
	const char *memtype[MEMINFO_ROWS] = { "RAM", "Swap" };
	FILE *procmeminfo = fopen("/proc/meminfo", "r");
	if (procmeminfo) {
		char buf[80], a[80];
		unsigned long v;
		while (fgets(buf, sizeof(buf), procmeminfo)) {
			if (2 == sscanf(buf, "%[^:]: %lu", a, &v)) {
				if (!strcasecmp(a, "MemTotal"))
					memstat[MEMINFO_RAM][MEMINFO_TOTAL] += v;
				else if (!strcasecmp(a, "MemFree"))
					memstat[MEMINFO_RAM][MEMINFO_FREE] += v;
				else if (!strcasecmp(a, "Inactive"))
					memstat[MEMINFO_RAM][MEMINFO_FREE] += v;
				else if (!strcasecmp(a, "SwapTotal"))
					memstat[MEMINFO_SWAP][MEMINFO_TOTAL] = v;
				else if (!strcasecmp(a, "SwapFree"))
					memstat[MEMINFO_SWAP][MEMINFO_FREE] += v;
			}
		}
		fclose(procmeminfo);
	}
	bool have_swap = memstat[MEMINFO_SWAP][MEMINFO_TOTAL];
	height += mheight;		// header
	height += mheight;		// ram
	height += have_swap * mheight;	// swap
	height += mheight/2;		// space

	std::ifstream in;

	std::map<std::string,bool> mounts;
	in.open("/proc/mounts");
	if (in.is_open()) {
		struct stat rec_st;
		struct statfs s;
		if (stat(g_settings.network_nfs_recordingdir.c_str(), &rec_st)
		|| (!::statfs(g_settings.network_nfs_recordingdir.c_str(), &s) && ((s.f_type == 0x72b6) || (s.f_type == 0x5941ff53))))
			memset(&rec_st, 0, sizeof(rec_st));

		std::map<dev_t,std::string> seen;
		std::string line;

		while (getline(in, line)) {
			size_t firstslash = line.find_first_of('/');
			size_t firstspace = line.find_first_of(' ');
			if ( (firstspace != string::npos && firstslash != string::npos && firstslash < firstspace) || (line.find("rootfs") == 0) ) {
				firstspace++;
				size_t nextspace = line.find_first_of(' ', firstspace);
				if (nextspace == string::npos || line.find("nodev", nextspace + 1) != string::npos)
					continue;
				std::string mountpoint = line.substr(firstspace, nextspace - firstspace);
				struct stat st;
				if (stat(mountpoint.c_str(), &st) || (seen.find(st.st_dev) != seen.end()))
					continue;
				seen[st.st_dev] = mountpoint;
				bool is_rec = (st.st_dev == rec_st.st_dev);
				mounts[mountpoint] = is_rec;
				int icon_space = is_rec ? 10 + icon_w : 0;
				const char *mnt = mountpoint.c_str();
				nameWidth = std::max(nameWidth, g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(basename((char *)mnt), true) + icon_space + 10);
			}
		}
		in.close();
	}

	height += mheight;			// header
	height += mounts.size() * mheight;	// file systems
	height += mheight/2;			// space

	int offsetw = nameWidth+ (sizeWidth+10)*3 +10+percWidth+10;
	width = offsetw + 10 + 120;

	int diff = frameBuffer->getScreenWidth() - width;
	if (diff < 0) {
		width += diff;
		offsetw += diff;
		nameWidth += diff;
	}
	height = h_max(height, 0);
	x = getScreenStartX(width);
	y = getScreenStartY(height);

	// fprintf(stderr, "CDBoxInfoWidget::CDBoxInfoWidget() x = %d, y = %d, width = %d height = %d\n", x, y, width, height);

	int ypos=y;

	//paint head
	std::string title(g_Locale->getText(LOCALE_EXTRA_DBOXINFO));
	std::map<std::string,std::string> cpuinfo;
	in.open("/proc/cpuinfo");
	if (in.is_open()) {
		std::string line;
		while (getline(in, line)) {
			size_t colon = line.find_first_of(':');
			if (colon != string::npos && colon > 1) {
				std::string key = line.substr(0, colon - 1);
				std::string val = line.substr(colon + 1);
				cpuinfo[trim(key)] = trim(val);
			}
		}
		in.close();
	}
	if (!cpuinfo["Hardware"].empty()) {
		title += ": ";
		title += cpuinfo["Hardware"];
	} else if (!cpuinfo["machine"].empty()) {
		title += ": ";
		title + cpuinfo["machine"];
	}

	CComponentsHeader header(x, ypos, width, hheight, title, NEUTRINO_ICON_SHELL);
	header.paint(CC_SAVE_SCREEN_NO);

	//paint body
	frameBuffer->paintBoxRel(x, ypos+ hheight, width, height- hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM);

	ypos += hheight + mheight/2;

	int head_info_rw = 0;
	for (int line = 0; line < head_info_lines; line++) {
		head_info_rw = std::max(head_info_rw, g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(head_info[line], true));
	}

	int dw = offsetw - 3*10 - head_info_rw;
	int buf_size=256;
	char ubuf[buf_size];
	char sbuf[buf_size];
	memset(sbuf, 0, 256);

	struct sysinfo info;
	sysinfo(&info);

	//get uptime
#if 0
	struct tm *current_time;
	time_t current_secs;
	time(&current_secs);
	current_time = localtime(&current_secs);

	snprintf( ubuf,buf_size, "%02d:%02d%s  up ",
		  current_time->tm_hour%12 ? current_time->tm_hour%12 : 12,
		  current_time->tm_min, current_time->tm_hour > 11 ? "pm" : "am");
	strcat(sbuf, ubuf);
#endif

	int updays, uphours, upminutes;

	updays = (int) info.uptime / (60*60*24);
	upminutes = (int) info.uptime / 60;
	uphours = (upminutes / 60) % 24;
	upminutes %= 60;

	if (updays) {
		snprintf(ubuf,buf_size, "%d day%s, ", updays, (updays != 1) ? "s" : "");
		strcat(sbuf, ubuf);
	}
	if (uphours) {
		snprintf(ubuf,buf_size,"%d hour%s, ", uphours, (uphours != 1) ? "s" : "");
		strcat(sbuf, ubuf);
	}
	snprintf(ubuf,buf_size,"%d minute%s", upminutes, (upminutes != 1) ? "s" : "");
	strcat(sbuf, ubuf);

	//paint uptime
	g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + 2*10 + head_info_rw, ypos+ mheight, dw, sbuf, COL_MENUCONTENT_TEXT);
	ypos += mheight;

	//get load avg
	snprintf(ubuf,buf_size, "%ld.%02ld, %ld.%02ld, %ld.%02ld",
		 LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]),
		 LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]),
		 LOAD_INT(info.loads[2]), LOAD_FRAC(info.loads[2]));

	//paint load avg
	g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + 2*10 + head_info_rw, ypos+ mheight, dw, ubuf, COL_MENUCONTENT_TEXT);
	ypos += mheight;

	//get current load
	cSysLoad *sysload = cSysLoad::getInstance();
	int data_last = sysload->data_last;

	//paint current load
	if (data_last > -1) {
		snprintf(ubuf, sizeof(ubuf), "%d%s%d%%", data_last/10, g_Locale->getText(LOCALE_UNIT_DECIMAL), data_last%10);
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + 2*10 + head_info_rw, ypos+ mheight, dw, ubuf, COL_MENUCONTENT_TEXT);
	}
	ypos += mheight;

	int pbw = width - offsetw - 10;
	if (pbw > 8) /* smaller progressbar is not useful ;) */
	{
		unsigned int h = cpuload_y1 - cpuload_y0;
		cpuload_y0 += y;
		cpuload_y1 += y;
		frameBuffer->paintBoxRel(x + offsetw, cpuload_y0, pbw, h, COL_MENUCONTENT_PLUS_2);

		int off = std::max(0, (int)sysload->data_avail - pbw);
		for (unsigned int i = 0; i < sysload->data_avail - off; i++) {
			if (sysload->data[i + off] > -1)
				frameBuffer->paintVLine(x+offsetw + i, cpuload_y1 - sysload->data[i + off] * h / 1000, cpuload_y1, COL_MENUCONTENT_PLUS_7);
		}
	}

	ypos += mheight/2;

	int headOffset=0;
	int mpOffset=0;
	int offsets[] = {
		10,
		nameWidth + 10,
		nameWidth + 10 + (sizeWidth+10)*1,
		nameWidth + 10 + (sizeWidth+10)*2,
		nameWidth + 10 + (sizeWidth+10)*3,
	};
	int widths[] = { 0, sizeWidth, sizeWidth, sizeWidth, percWidth };

	const int headSize = 5;
	int maxWidth[headSize];
	memset(maxWidth, 0, headSize * sizeof(int));

	int ypos_mem_head = ypos;
	ypos += mheight;

	for (int row = 0; row < 1 + have_swap; row++) {
		std::string tmp;
		memstat[row][MEMINFO_USED] = memstat[row][MEMINFO_TOTAL] - memstat[row][MEMINFO_FREE];
		for (int column = 0; column < headSize; column++) {
			switch (column) {
				case 0:
					tmp = memtype[row];
					break;
				case 1:
					tmp = bytes2string(memstat[row][MEMINFO_TOTAL] << 10);
					break;
				case 2:
					tmp = bytes2string(memstat[row][MEMINFO_USED] << 10);
					break;
				case 3:
					tmp = bytes2string(memstat[row][MEMINFO_FREE] << 10);
					break;
				case 4:
					tmp = to_string(memstat[row][MEMINFO_TOTAL] ? (memstat[row][MEMINFO_USED] * 100) / memstat[row][MEMINFO_TOTAL] : 0) + "%";
					break;
			}
			mpOffset = offsets[column];
			int space = 0;
			int rw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true);
			if (column > 0) {
				space = widths[column] - rw;
			}
			maxWidth[column] = std::max(maxWidth[column], rw)+6;
			if ((mpOffset + space + maxWidth[column]) > width)
				maxWidth[column] = width - (mpOffset + space);
			g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + mpOffset + space, ypos+ mheight, maxWidth[column], tmp, COL_MENUCONTENT_TEXT);
		}
		if (pbw > 8) /* smaller progressbar is not useful ;) */
		{
			CProgressBar pb(x+offsetw, ypos+3, pbw, mheight-10);
			pb.setBlink();
			pb.setInvert();
			pb.setValues(memstat[row][MEMINFO_TOTAL] ? (memstat[row][MEMINFO_USED] * 100) / memstat[row][MEMINFO_TOTAL] : 0, 100);
			pb.paint(false);
		}
		ypos += mheight;
	}
	ypos += mheight/2;

	int ypos_mnt_head = ypos;
	ypos += mheight;

	int width_i = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth("i", true);

	for (std::map<std::string, bool>::iterator it = mounts.begin(); it != mounts.end(); ++it) {
		struct statfs s;
		if (::statfs((*it).first.c_str(), &s) == 0) {
			if (s.f_blocks > 0) {
				uint64_t bytes_total = s.f_blocks * s.f_bsize;
				uint64_t bytes_free  = s.f_bfree  * s.f_bsize;
				uint64_t bytes_used = bytes_total - bytes_free;
				int percent_used = (bytes_used * 200 + bytes_total) / 2 / bytes_total;
				//paint mountpoints
				for (int column = 0; column < headSize; column++) {
					std::string tmp;
					const char *mnt;
					mpOffset = offsets[column];
					int _w = maxWidth[column];
					switch (column) {
					case 0:
						tmp = (*it).first;
						if (tmp == "/")
							tmp = "rootfs";
						mnt = tmp.c_str();
						tmp = basename((char *)mnt);
						_w = nameWidth - mpOffset;
						if ((*it).second)
							_w -= icon_w + 10;
						_w += width_i/2;
						break;
					case 1:
						tmp = bytes2string(bytes_total, false);
						break;
					case 2:
						tmp = bytes2string(bytes_used, false);
						break;
					case 3:
						tmp = bytes2string(bytes_free, false);
						break;
					case 4:
						tmp = to_string(percent_used) + "%";
						break;
					}
					int space = 0;
					if (column > 0) {
						int rw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true);
						maxWidth[column] = std::max(maxWidth[column], rw);
						space = widths[column] - rw;
						_w = rw;
					}
					if ((mpOffset + space + _w) > width)
						_w = width - (mpOffset + space);
					g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + mpOffset + space, ypos+ mheight, _w, tmp, COL_MENUCONTENT_TEXT);
					if ((*it).second && icon_w>0 && icon_h>0)
						frameBuffer->paintIcon(NEUTRINO_ICON_REC, x + nameWidth - icon_w + width_i/2, ypos + (mheight/2 - icon_h/2));
				}
				if (pbw > 8) /* smaller progressbar is not useful ;) */
				{
					CProgressBar pb(x+offsetw, ypos+3, pbw, mheight-10);
					pb.setBlink();
					pb.setInvert();
					pb.setValues(percent_used, 100);
					pb.paint(false);
				}
				ypos += mheight;
			}
		}
		if (ypos > y + height - mheight)	/* the screen is not high enough */
			break;				/* todo: scrolling? */
	}
	// paint info heads
	head_info_ypos += y;
	for (int line = 0; line < head_info_lines; line++) {
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + 10, head_info_ypos + mheight*(line+1), head_info_rw, head_info[line], COL_MENUCONTENTINACTIVE_TEXT);
	}
	// paint mem head
	const char *head_mem[headSize] = {"Memory", "Size", "Used", "Available", "Use"};
	for (int column = 0; column < headSize; column++) {
		headOffset = offsets[column];
		int space = 0;
		int rw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(head_mem[column], true);
		int _w = rw;
		if (column > 0) {
			if (rw > maxWidth[column])
				space = widths[column] - rw;
			else
				space = widths[column] - maxWidth[column] + (maxWidth[column] - rw)/2;
		}
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ headOffset + space, ypos_mem_head + mheight, _w, head_mem[column], COL_MENUCONTENTINACTIVE_TEXT);
	}
	// paint mount head
	const char *head_mnt[headSize] = {"Filesystem", "Size", "Used", "Available", "Use"};
	for (int column = 0; column < headSize; column++) {
		headOffset = offsets[column];
		int space = 0;
		int rw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(head_mnt[column], true);
		int _w = rw;
		if (column > 0) {
			if (rw > maxWidth[column])
				space = widths[column] - rw;
			else
				space = widths[column] - maxWidth[column] + (maxWidth[column] - rw)/2;
		}
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ headOffset + space, ypos_mnt_head + mheight, _w, head_mnt[column], COL_MENUCONTENTINACTIVE_TEXT);
	}
}