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

📄 array.c

📁 嵌入式ARM的一些源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		int count = 0;

		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])))
#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 /* !NO_MM */
	}
	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_MM
static 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);
}

static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
	int * pages, int * shared, int * dirty, int * total)
{

⌨️ 快捷键说明

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