array.c

来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 1,284 行 · 第 1/3 页

C
1,284
字号
		stack_page = p->kernel_stack_page;		if (!stack_page)			return 0;		ebp = p->tss.ebp;		do {			if (ebp < stack_page || ebp >= 4092+stack_page)				return 0;			eip = *(unsigned long *) (ebp+4);			if (eip < (unsigned long) interruptible_sleep_on			    || eip >= (unsigned long) add_timer)				return eip;			ebp = *(unsigned long *) ebp;		} while (count++ < 16);	}#elif defined(__alpha__)	/*	 * This one depends on the frame size of schedule().  Do a	 * "disass schedule" in gdb to find the frame size.  Also, the	 * code assumes that sleep_on() follows immediately after	 * interruptible_sleep_on() and that add_timer() follows	 * immediately after interruptible_sleep().  Ugly, isn't it?	 * Maybe adding a wchan field to task_struct would be better,	 * after all...	 */	{	    unsigned long schedule_frame;	    unsigned long pc;	    pc = thread_saved_pc(&p->tss);	    if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {		schedule_frame = ((unsigned long *)p->tss.ksp)[6];		return ((unsigned long *)schedule_frame)[12];	    }	    return pc;	}#endif	return 0;}#if defined(__i386__)# define KSTK_EIP(tsk)	(((unsigned long *)tsk->kernel_stack_page)[1019])# define KSTK_ESP(tsk)	(((unsigned long *)tsk->kernel_stack_page)[1022])#elif defined(__alpha__)  /*   * See arch/alpha/kernel/ptrace.c for details.   */# define PT_REG(reg)		(PAGE_SIZE - sizeof(struct pt_regs)	\				 + (long)&((struct pt_regs *)0)->reg)# define KSTK_EIP(tsk)	(*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))# define KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->tss.usp)#elif defined(__sparc__)# define PT_REG(reg)            (PAGE_SIZE - sizeof(struct pt_regs)     \                                 + (long)&((struct pt_regs *)0)->reg)# define KSTK_EIP(tsk)  (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))# define KSTK_ESP(tsk)  (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(u_regs[UREG_FP])))#elif defined(__CRIS__)     /* TODO - get these from the pt_regs on top of the kernel stack page */#define KSTK_EIP(tsk) 5#define KSTK_ESP(tsk) 6#endif/* Gcc optimizes away "strlen(x)" for constant x */#define ADDBUF(buffer, string) \do { memcpy(buffer, string, strlen(string)); \     buffer += strlen(string); } while (0)static inline char * task_name(struct task_struct *p, char * buf){	int i;	char * name;	ADDBUF(buf, "Name:\t");	name = p->comm;	i = sizeof(p->comm);	do {		unsigned char c = *name;		name++;		i--;		*buf = c;		if (!c)			break;		if (c == '\\') {			buf[1] = c;			buf += 2;			continue;		}		if (c == '\n') {			buf[0] = '\\';			buf[1] = 'n';			buf += 2;			continue;		}		buf++;	} while (i);	*buf = '\n';	return buf+1;}static inline char * task_state(struct task_struct *p, char *buffer){#define NR_STATES (sizeof(states)/sizeof(const char *))	unsigned int n = p->state;	static const char * states[] = {		"R (running)",		"S (sleeping)",		"D (disk sleep)",		"Z (zombie)",		"T (stopped)",		"W (paging)",		". Huh?"	};	if (n >= NR_STATES)		n = NR_STATES-1;	buffer += sprintf(buffer,		"State:\t%s\n"		"Pid:\t%d\n"		"PPid:\t%d\n"		"Uid:\t%d\t%d\t%d\t%d\n"		"Gid:\t%d\t%d\t%d\t%d\n",		states[n],		p->pid, p->p_pptr->pid,		p->uid, p->euid, p->suid, p->fsuid,		p->gid, p->egid, p->sgid, p->fsgid);	return buffer;}static inline char * task_mem(struct task_struct *p, char *buffer){#ifndef NO_MM	struct mm_struct * mm = p->mm;	if (mm && mm != &init_mm) {		struct vm_area_struct * vma = mm->mmap;		unsigned long data = 0, stack = 0;		unsigned long exec = 0, lib = 0;		for (vma = mm->mmap; vma; vma = vma->vm_next) {			unsigned long len = (vma->vm_end - vma->vm_start) >> 10;			if (!vma->vm_inode) {				data += len;				if (vma->vm_flags & VM_GROWSDOWN)					stack += len;				continue;			}			if (vma->vm_flags & VM_WRITE)				continue;			if (vma->vm_flags & VM_EXEC) {				exec += len;				if (vma->vm_flags & VM_EXECUTABLE)					continue;				lib += len;			}		}			buffer += sprintf(buffer,			"VmSize:\t%8lu kB\n"			"VmLck:\t%8lu kB\n"			"VmRSS:\t%8lu kB\n"			"VmData:\t%8lu kB\n"			"VmStk:\t%8lu kB\n"			"VmExe:\t%8lu kB\n"			"VmLib:\t%8lu kB\n",			mm->total_vm << (PAGE_SHIFT-10),			mm->locked_vm << (PAGE_SHIFT-10),			mm->rss << (PAGE_SHIFT-10),			data - stack, stack,			exec - lib, lib);	}#else /* NO_MM */	unsigned long bytes = 0, sbytes = 0;        struct mm_tblock_struct * tblock;                /* Logic: we've got two memory sums for each process, "shared", and         * "non-shared". Shared memory may get counted more then once, for         * each process that owns it. Non-shared memory is counted         * accurately.         *         *     -- Kenneth Albanowski         */	for(tblock = &p->mm->tblock;tblock;tblock=tblock->next) {				if (tblock->rblock) {						bytes += ksize(tblock);						if ((p->mm->count > 1) || (tblock->rblock->refcount > 1)			    ) {				sbytes += ksize(tblock->rblock->kblock);				sbytes += ksize(tblock->rblock) ;			} else {				bytes += ksize(tblock->rblock->kblock);				bytes += ksize(tblock->rblock) ;			}					}					}		((p->mm->count > 1) ? sbytes : bytes) += ksize(p->mm);	((p->fs->count > 1) ? sbytes : bytes) += ksize(p->fs);	((p->files->count > 1) ? sbytes : bytes) += ksize(p->files);	((p->sig->count > 1) ? sbytes : bytes) += ksize(p->sig);	bytes += ksize(p); 		bytes += PAGE_SIZE; /* Kernel stack */		buffer += sprintf(buffer,			  "Mem:\t%8lu bytes\n"			  "Shared:\t%8lu bytes\n",			  bytes,			  sbytes);#endif /* NO_MM */	return buffer;}static inline char * task_sig(struct task_struct *p, char *buffer){	buffer += sprintf(buffer,		"SigPnd:\t%08lx\n"		"SigBlk:\t%08lx\n",		p->signal, p->blocked);	if (p->sig) {		struct sigaction * action = p->sig->action;		unsigned long sig_ign = 0, sig_caught = 0;		unsigned long bit = 1;		int i;		for (i = 0; i < 32; i++) {			switch((unsigned long) action->sa_handler) {				case 0:					break;				case 1:					sig_ign |= bit;					break;				default:					sig_caught |= bit;			}			bit <<= 1;			action++;		}		buffer += sprintf(buffer,			"SigIgn:\t%08lx\n"			"SigCgt:\t%08lx\n",			sig_ign, sig_caught);	}	return buffer;}static int get_status(int pid, char * buffer){	char * orig = buffer;	struct task_struct ** p = get_task(pid), *tsk;	if (!p || (tsk = *p) == NULL)		return 0;	buffer = task_name(tsk, buffer);	buffer = task_state(tsk, buffer);	buffer = task_mem(tsk, buffer);	buffer = task_sig(tsk, buffer);	return buffer - orig;}static int get_stat(int pid, char * buffer){	struct task_struct ** p = get_task(pid), *tsk;	unsigned long sigignore=0, sigcatch=0, wchan;	unsigned long vsize, eip, esp;	long priority, nice;	int i,tty_pgrp;	char state;	if (!p || (tsk = *p) == NULL)		return 0;	if (tsk->state < 0 || tsk->state > 5)		state = '.';	else		state = "RSDZTW"[tsk->state];	vsize = eip = esp = 0;	if (tsk->mm && tsk->mm != &init_mm) {#ifndef NO_MM		struct vm_area_struct *vma = tsk->mm->mmap;		while (vma) {			vsize += vma->vm_end - vma->vm_start;			vma = vma->vm_next;		}		if (tsk->kernel_stack_page) {			eip = KSTK_EIP(tsk);			esp = KSTK_ESP(tsk);		}#endif	}	wchan = get_wchan(tsk);	if (tsk->sig) {		unsigned long bit = 1;		for(i=0; i<32; ++i) {			switch((unsigned long) tsk->sig->action[i].sa_handler) {				case 0:					break;				case 1:					sigignore |= bit;					break;				default:					sigcatch |= bit;			}			bit <<= 1;		}	}	if (tsk->tty)		tty_pgrp = tsk->tty->pgrp;	else		tty_pgrp = -1;	/* scale priority and nice values from timeslices to -20..20 */	/* to make it look like a "normal" unix priority/nice value  */	priority = tsk->counter;	priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY;	nice = tsk->priority;	nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;	return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \%lu %lu %lu %lu %lu %lu %lu %lu\n",		pid,		tsk->comm,		state,		tsk->p_pptr->pid,		tsk->pgrp,		tsk->session,	        tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0,		tty_pgrp,		tsk->flags,		tsk->min_flt,		tsk->cmin_flt,		tsk->maj_flt,		tsk->cmaj_flt,		tsk->utime,		tsk->stime,		tsk->cutime,		tsk->cstime,		priority,		nice,		tsk->timeout,		tsk->it_real_value,		tsk->start_time,		vsize,		tsk->mm ? tsk->mm->rss : 0, /* you might want to shift this left 3 */		tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0,		tsk->mm ? tsk->mm->start_code : 0,		tsk->mm ? tsk->mm->end_code : 0,		tsk->mm ? tsk->mm->start_stack : 0,		esp,		eip,		tsk->signal,		tsk->blocked,		sigignore,		sigcatch,		wchan,		tsk->nswap,		tsk->cnswap);}		#ifndef NO_MMstatic inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,	int * pages, int * shared, int * dirty, int * total){	pte_t * pte;	unsigned long end;	if (pmd_none(*pmd))		return;	if (pmd_bad(*pmd)) {		printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));		pmd_clear(pmd);		return;	}	pte = pte_offset(pmd, address);	address &= ~PMD_MASK;	end = address + size;	if (end > PMD_SIZE)		end = PMD_SIZE;	do {		pte_t page = *pte;		address += PAGE_SIZE;		pte++;		if (pte_none(page))			continue;		++*total;		if (!pte_present(page))			continue;		++*pages;		if (pte_dirty(page))			++*dirty;		if (pte_page(page) >= high_memory)			continue;		if (mem_map[MAP_NR(pte_page(page))].count > 1)			++*shared;	} while (address < end);}static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,	int * pages, int * shared, int * dirty, int * total){	pmd_t * pmd;	unsigned long end;	if (pgd_none(*pgd))		return;	if (pgd_bad(*pgd)) {		printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));		pgd_clear(pgd);		return;	}	pmd = pmd_offset(pgd, address);	address &= ~PGDIR_MASK;	end = address + size;	if (end > PGDIR_SIZE)		end = PGDIR_SIZE;	do {		statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);		address = (address + PMD_SIZE) & PMD_MASK;		pmd++;	} while (address < end);}

⌨️ 快捷键说明

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