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

📄 array.c

📁 嵌入式ARM的一些源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	while (address < end) {
		statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
		address = (address + PGDIR_SIZE) & PGDIR_MASK;
		pgd++;
	}
}

static int get_statm(int pid, char * buffer)
{
	struct task_struct ** p = get_task(pid), *tsk;
	int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;

	if (!p || (tsk = *p) == NULL)
		return 0;
	if (tsk->mm && tsk->mm != &init_mm) {
		struct vm_area_struct * vma = tsk->mm->mmap;

		while (vma) {
			pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
			int pages = 0, shared = 0, dirty = 0, total = 0;

			statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
			resident += pages;
			share += shared;
			dt += dirty;
			size += total;
			if (vma->vm_flags & VM_EXECUTABLE)
				trs += pages;	/* text */
			else if (vma->vm_flags & VM_GROWSDOWN)
				drs += pages;	/* stack */
			else if (vma->vm_end > 0x60000000)
				lrs += pages;	/* library */
			else
				drs += pages;
			vma = vma->vm_next;
		}
	}
	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
		       size, resident, share, trs, lrs, drs, dt);
}

/*
 * The way we support synthetic files > 4K
 * - without storing their contents in some buffer and
 * - without walking through the entire synthetic file until we reach the
 *   position of the requested data
 * is to cleverly encode the current position in the file's f_pos field.
 * There is no requirement that a read() call which returns `count' bytes
 * of data increases f_pos by exactly `count'.
 *
 * This idea is Linus' one. Bruno implemented it.
 */

/*
 * For the /proc/<pid>/maps file, we use fixed length records, each containing
 * a single line.
 */
#define MAPS_LINE_LENGTH	1024
#define MAPS_LINE_SHIFT		10
/*
 * f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH
 *         + (index into the line)
 */
/* for systems with sizeof(void*) == 4: */
#define MAPS_LINE_FORMAT4	  "%08lx-%08lx %s %08lx %s %lu\n"
#define MAPS_LINE_MAX4	49 /* sum of 8  1  8  1 4 1 8 1 5 1 10 1 */

/* for systems with sizeof(void*) == 8: */
#define MAPS_LINE_FORMAT8	  "%016lx-%016lx %s %016lx %s %lu\n"
#define MAPS_LINE_MAX8	73 /* sum of 16  1  16  1 4 1 16 1 5 1 10 1 */

#define MAPS_LINE_MAX	MAPS_LINE_MAX8


static int read_maps (int pid, struct file * file, char * buf, int count)
{
	struct task_struct ** p = get_task(pid);
	char * destptr;
	loff_t lineno;
	int column;
	struct vm_area_struct * map;
	int i;

	if (!p || !*p)
		return -EINVAL;

	if (!(*p)->mm || (*p)->mm == &init_mm || count == 0)
		return 0;

	/* decode f_pos */
	lineno = file->f_pos >> MAPS_LINE_SHIFT;
	column = file->f_pos & (MAPS_LINE_LENGTH-1);

	/* quickly go to line lineno */
	for (map = (*p)->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++)
		continue;

	destptr = buf;

	for ( ; map ; ) {
		/* produce the next line */
		char line[MAPS_LINE_MAX+1];
		char str[5], *cp = str;
		int flags;
		kdev_t dev;
		unsigned long ino;
		int len;

		flags = map->vm_flags;

		*cp++ = flags & VM_READ ? 'r' : '-';
		*cp++ = flags & VM_WRITE ? 'w' : '-';
		*cp++ = flags & VM_EXEC ? 'x' : '-';
		*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
		*cp++ = 0;

		if (map->vm_inode != NULL) {
			dev = map->vm_inode->i_dev;
			ino = map->vm_inode->i_ino;
		} else {
			dev = 0;
			ino = 0;
		}

		len = sprintf(line,
			      sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8,
			      map->vm_start, map->vm_end, str, map->vm_offset,
			      kdevname(dev), ino);

		if (column >= len) {
			column = 0; /* continue with next line at column 0 */
			lineno++;
			map = map->vm_next;
			continue;
		}

		i = len-column;
		if (i > count)
			i = count;
		memcpy_tofs(destptr, line+column, i);
		destptr += i; count -= i;
		column += i;
		if (column >= len) {
			column = 0; /* next time: next line at column 0 */
			lineno++;
			map = map->vm_next;
		}

		/* done? */
		if (count == 0)
			break;

		/* By writing to user space, we might have slept.
		 * Stop the loop, to avoid a race condition.
		 */
		if (*p != current)
			break;
	}

	/* encode f_pos */
	file->f_pos = (lineno << MAPS_LINE_SHIFT) + column;

	return destptr-buf;
}
#endif /* !NO_MM */

#ifdef CONFIG_MODULES
extern int get_module_list(char *);
extern int get_ksyms_list(char *, char **, off_t, int);
#endif
extern int get_device_list(char *);
extern int get_filesystem_list(char *);
extern int get_filesystem_info( char * );
extern int get_irq_list(char *);
extern int get_serialinfo(char *);
extern int get_dma_list(char *);
extern int get_cpuinfo(char *);
extern int get_pci_list(char*);
extern int get_md_status (char *);
extern int get_rtc_status (char *);
extern int get_locks_status (char *, char **, off_t, int);
#ifdef __SMP_PROF__
extern int get_smp_prof_list(char *);
#endif

static int get_root_array(char * page, int type, char **start, off_t offset, int length)
{
	switch (type) {
		case PROC_LOADAVG:
			return get_loadavg(page);

		case PROC_UPTIME:
			return get_uptime(page);

		case PROC_MEMINFO:
			return get_meminfo(page);

#ifdef CONFIG_PCI
  	        case PROC_PCI:
			return get_pci_list(page);
#endif
			
		case PROC_CPUINFO:
			return get_cpuinfo(page);

		case PROC_VERSION:
			return get_version(page);

#ifdef CONFIG_DEBUG_MALLOC
		case PROC_MALLOC:
			return get_malloc(page);
#endif

#ifdef CONFIG_MODULES
		case PROC_MODULES:
			return get_module_list(page);

		case PROC_KSYMS:
			return get_ksyms_list(page, start, offset, length);
#endif

		case PROC_STAT:
			return get_kstat(page);

		case PROC_DEVICES:
			return get_device_list(page);

		case PROC_INTERRUPTS:
			return get_irq_list(page);

		case PROC_SERIAL:
			return get_serialinfo(page);

		case PROC_FILESYSTEMS:
			return get_filesystem_list(page);

		case PROC_DMA:
			return get_dma_list(page);

		case PROC_IOPORTS:
			return get_ioport_list(page);
#ifdef CONFIG_BLK_DEV_MD
	        case PROC_MD:
			return get_md_status(page);
#endif
#ifdef __SMP_PROF__
		case PROC_SMP_PROF:
			return get_smp_prof_list(page);
#endif
		case PROC_CMDLINE:
			return get_cmdline(page);

                case PROC_MTAB:
                       return get_filesystem_info( page );
#ifdef CONFIG_RTC
		case PROC_RTC:
			return get_rtc_status(page);
#endif
		case PROC_LOCKS:
			return get_locks_status(page, start, offset, length);
	}
	return -EBADF;
}

static int get_process_array(char * page, int pid, int type)
{
	switch (type) {
		case PROC_PID_STATUS:
			return get_status(pid, page);
		case PROC_PID_ENVIRON:
			return get_env(pid, page);
		case PROC_PID_CMDLINE:
			return get_arg(pid, page);
		case PROC_PID_STAT:
			return get_stat(pid, page);
#ifndef NO_MM
		case PROC_PID_STATM:
			return get_statm(pid, page);
#endif /* !NO_MM */
	}
	return -EBADF;
}


static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length)
{
	if (pid)
		return get_process_array(page, pid, type);
	return get_root_array(page, type, start, offset, length);
}

#define PROC_BLOCK_SIZE	(3*1024)		/* 4K page size but our output routines use some slack for overruns */

static int array_read(struct inode * inode, struct file * file,char * buf, int count)
{
	unsigned long page;
	char *start;
	int length;
	int end;
	unsigned int type, pid;
	struct proc_dir_entry *dp;

	if (count < 0)
		return -EINVAL;
	if (count > PROC_BLOCK_SIZE)
		count = PROC_BLOCK_SIZE;
	if (!(page = __get_free_page(GFP_KERNEL)))
		return -ENOMEM;
	type = inode->i_ino;
	pid = type >> 16;
	type &= 0x0000ffff;
	start = NULL;
	dp = (struct proc_dir_entry *) inode->u.generic_ip;
	if (dp->get_info)
		length = dp->get_info((char *)page, &start, file->f_pos,
				      count, 0);
	else
		length = fill_array((char *) page, pid, type,
				    &start, file->f_pos, count);
	if (length < 0) {
		free_page(page);
		return length;
	}
	if (start != NULL) {
		/* We have had block-adjusting processing! */
		memcpy_tofs(buf, start, length);
		file->f_pos += length;
		count = length;
	} else {
		/* Static 4kB (or whatever) block capacity */
		if (file->f_pos >= length) {
			free_page(page);
			return 0;
		}
		if (count + file->f_pos > length)
			count = length - file->f_pos;
		end = count + file->f_pos;
		memcpy_tofs(buf, (char *) page + file->f_pos, count);
		file->f_pos = end;
	}
	free_page(page);
	return count;
}

static struct file_operations proc_array_operations = {
	NULL,		/* array_lseek */
	array_read,
	NULL,		/* array_write */
	NULL,		/* array_readdir */
	NULL,		/* array_select */
	NULL,		/* array_ioctl */
	NULL,		/* mmap */
	NULL,		/* no special open code */
	NULL,		/* no special release code */
	NULL		/* can't fsync */
};

struct inode_operations proc_array_inode_operations = {
	&proc_array_operations,	/* default base directory file-ops */
	NULL,			/* create */
	NULL,			/* lookup */
	NULL,			/* link */
	NULL,			/* unlink */
	NULL,			/* symlink */
	NULL,			/* mkdir */
	NULL,			/* rmdir */
	NULL,			/* mknod */
	NULL,			/* rename */
	NULL,			/* readlink */
	NULL,			/* follow_link */
	NULL,			/* readpage */
	NULL,			/* writepage */
	NULL,			/* bmap */
	NULL,			/* truncate */
	NULL			/* permission */
};

static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count)
{
#ifndef NO_MM
	unsigned int pid = inode->i_ino >> 16;
	unsigned int type = inode->i_ino & 0x0000ffff;

	if (count < 0)
		return -EINVAL;

	switch (type) {
		case PROC_PID_MAPS:
			return read_maps(pid, file, buf, count);
	}
#endif /* !NO_MM */
	return -EINVAL;
}

static struct file_operations proc_arraylong_operations = {
	NULL,		/* array_lseek */
	arraylong_read,
	NULL,		/* array_write */
	NULL,		/* array_readdir */
	NULL,		/* array_select */
	NULL,		/* array_ioctl */
	NULL,		/* mmap */
	NULL,		/* no special open code */
	NULL,		/* no special release code */
	NULL		/* can't fsync */
};

struct inode_operations proc_arraylong_inode_operations = {
	&proc_arraylong_operations,	/* default base directory file-ops */
	NULL,			/* create */
	NULL,			/* lookup */
	NULL,			/* link */
	NULL,			/* unlink */
	NULL,			/* symlink */
	NULL,			/* mkdir */
	NULL,			/* rmdir */
	NULL,			/* mknod */
	NULL,			/* rename */
	NULL,			/* readlink */
	NULL,			/* follow_link */
	NULL,			/* readpage */
	NULL,			/* writepage */
	NULL,			/* bmap */
	NULL,			/* truncate */
	NULL			/* permission */
};

⌨️ 快捷键说明

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