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 + -
显示快捷键?