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

📄 acct.c

📁 linux 2.6.19 kernel source code before patching
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (acct_globals.file &&	    acct_globals.file->f_path.mnt->mnt_sb == sb) {		acct_file_reopen(NULL);	}	spin_unlock(&acct_globals.lock);}/* *  encode an unsigned long into a comp_t * *  This routine has been adopted from the encode_comp_t() function in *  the kern_acct.c file of the FreeBSD operating system. The encoding *  is a 13-bit fraction with a 3-bit (base 8) exponent. */#define	MANTSIZE	13			/* 13 bit mantissa. */#define	EXPSIZE		3			/* Base 8 (3 bit) exponent. */#define	MAXFRACT	((1 << MANTSIZE) - 1)	/* Maximum fractional value. */static comp_t encode_comp_t(unsigned long value){	int exp, rnd;	exp = rnd = 0;	while (value > MAXFRACT) {		rnd = value & (1 << (EXPSIZE - 1));	/* Round up? */		value >>= EXPSIZE;	/* Base 8 exponent == 3 bit shift. */		exp++;	}	/*         * If we need to round up, do it (and handle overflow correctly).         */	if (rnd && (++value > MAXFRACT)) {		value >>= EXPSIZE;		exp++;	}	/*         * Clean it up and polish it off.         */	exp <<= MANTSIZE;		/* Shift the exponent into place */	exp += value;			/* and add on the mantissa. */	return exp;}#if ACCT_VERSION==1 || ACCT_VERSION==2/* * encode an u64 into a comp2_t (24 bits) * * Format: 5 bit base 2 exponent, 20 bits mantissa. * The leading bit of the mantissa is not stored, but implied for * non-zero exponents. * Largest encodable value is 50 bits. */#define MANTSIZE2       20                      /* 20 bit mantissa. */#define EXPSIZE2        5                       /* 5 bit base 2 exponent. */#define MAXFRACT2       ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */#define MAXEXP2         ((1 <<EXPSIZE2) - 1)    /* Maximum exponent. */static comp2_t encode_comp2_t(u64 value){        int exp, rnd;        exp = (value > (MAXFRACT2>>1));        rnd = 0;        while (value > MAXFRACT2) {                rnd = value & 1;                value >>= 1;                exp++;        }        /*         * If we need to round up, do it (and handle overflow correctly).         */        if (rnd && (++value > MAXFRACT2)) {                value >>= 1;                exp++;        }        if (exp > MAXEXP2) {                /* Overflow. Return largest representable number instead. */                return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;        } else {                return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));        }}#endif#if ACCT_VERSION==3/* * encode an u64 into a 32 bit IEEE float */static u32 encode_float(u64 value){	unsigned exp = 190;	unsigned u;	if (value==0) return 0;	while ((s64)value > 0){		value <<= 1;		exp--;	}	u = (u32)(value >> 40) & 0x7fffffu;	return u | (exp << 23);}#endif/* *  Write an accounting entry for an exiting process * *  The acct_process() call is the workhorse of the process *  accounting system. The struct acct is built here and then written *  into the accounting file. This function should only be called from *  do_exit(). *//* *  do_acct_process does all actual work. Caller holds the reference to file. */static void do_acct_process(struct file *file){	struct pacct_struct *pacct = &current->signal->pacct;	acct_t ac;	mm_segment_t fs;	unsigned long flim;	u64 elapsed;	u64 run_time;	struct timespec uptime;	struct tty_struct *tty;	/*	 * First check to see if there is enough free_space to continue	 * the process accounting system.	 */	if (!check_free_space(file))		return;	/*	 * Fill the accounting struct with the needed info as recorded	 * by the different kernel functions.	 */	memset((caddr_t)&ac, 0, sizeof(acct_t));	ac.ac_version = ACCT_VERSION | ACCT_BYTEORDER;	strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));	/* calculate run_time in nsec*/	do_posix_clock_monotonic_gettime(&uptime);	run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;	run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC		       + current->group_leader->start_time.tv_nsec;	/* convert nsec -> AHZ */	elapsed = nsec_to_AHZ(run_time);#if ACCT_VERSION==3	ac.ac_etime = encode_float(elapsed);#else	ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?	                       (unsigned long) elapsed : (unsigned long) -1l);#endif#if ACCT_VERSION==1 || ACCT_VERSION==2	{		/* new enlarged etime field */		comp2_t etime = encode_comp2_t(elapsed);		ac.ac_etime_hi = etime >> 16;		ac.ac_etime_lo = (u16) etime;	}#endif	do_div(elapsed, AHZ);	ac.ac_btime = xtime.tv_sec - elapsed;	/* we really need to bite the bullet and change layout */	ac.ac_uid = current->uid;	ac.ac_gid = current->gid;#if ACCT_VERSION==2	ac.ac_ahz = AHZ;#endif#if ACCT_VERSION==1 || ACCT_VERSION==2	/* backward-compatible 16 bit fields */	ac.ac_uid16 = current->uid;	ac.ac_gid16 = current->gid;#endif#if ACCT_VERSION==3	ac.ac_pid = current->tgid;	ac.ac_ppid = current->parent->tgid;#endif	spin_lock_irq(&current->sighand->siglock);	tty = current->signal->tty;	ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));	ac.ac_flag = pacct->ac_flag;	ac.ac_mem = encode_comp_t(pacct->ac_mem);	ac.ac_minflt = encode_comp_t(pacct->ac_minflt);	ac.ac_majflt = encode_comp_t(pacct->ac_majflt);	ac.ac_exitcode = pacct->ac_exitcode;	spin_unlock_irq(&current->sighand->siglock);	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);	ac.ac_swaps = encode_comp_t(0);	/*         * Kernel segment override to datasegment and write it         * to the accounting file.         */	fs = get_fs();	set_fs(KERNEL_DS);	/* 	 * Accounting records are not subject to resource limits. 	 */	flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;	file->f_op->write(file, (char *)&ac,			       sizeof(acct_t), &file->f_pos);	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;	set_fs(fs);}/** * acct_init_pacct - initialize a new pacct_struct * @pacct: per-process accounting info struct to initialize */void acct_init_pacct(struct pacct_struct *pacct){	memset(pacct, 0, sizeof(struct pacct_struct));	pacct->ac_utime = pacct->ac_stime = cputime_zero;}/** * acct_collect - collect accounting information into pacct_struct * @exitcode: task exit code * @group_dead: not 0, if this thread is the last one in the process. */void acct_collect(long exitcode, int group_dead){	struct pacct_struct *pacct = &current->signal->pacct;	unsigned long vsize = 0;	if (group_dead && current->mm) {		struct vm_area_struct *vma;		down_read(&current->mm->mmap_sem);		vma = current->mm->mmap;		while (vma) {			vsize += vma->vm_end - vma->vm_start;			vma = vma->vm_next;		}		up_read(&current->mm->mmap_sem);	}	spin_lock_irq(&current->sighand->siglock);	if (group_dead)		pacct->ac_mem = vsize / 1024;	if (thread_group_leader(current)) {		pacct->ac_exitcode = exitcode;		if (current->flags & PF_FORKNOEXEC)			pacct->ac_flag |= AFORK;	}	if (current->flags & PF_SUPERPRIV)		pacct->ac_flag |= ASU;	if (current->flags & PF_DUMPCORE)		pacct->ac_flag |= ACORE;	if (current->flags & PF_SIGNALED)		pacct->ac_flag |= AXSIG;	pacct->ac_utime = cputime_add(pacct->ac_utime, current->utime);	pacct->ac_stime = cputime_add(pacct->ac_stime, current->stime);	pacct->ac_minflt += current->min_flt;	pacct->ac_majflt += current->maj_flt;	spin_unlock_irq(&current->sighand->siglock);}/** * acct_process - now just a wrapper around do_acct_process * @exitcode: task exit code * * handles process accounting for an exiting task */void acct_process(void){	struct file *file = NULL;	/*	 * accelerate the common fastpath:	 */	if (!acct_globals.file)		return;	spin_lock(&acct_globals.lock);	file = acct_globals.file;	if (unlikely(!file)) {		spin_unlock(&acct_globals.lock);		return;	}	get_file(file);	spin_unlock(&acct_globals.lock);	do_acct_process(file);	fput(file);}

⌨️ 快捷键说明

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