亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? posix-cpu-timers.c

?? linux 2.6.19 kernel source code before patching
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * Implement CPU time clocks for the POSIX clock interface. */#include <linux/sched.h>#include <linux/posix-timers.h>#include <asm/uaccess.h>#include <linux/errno.h>static int check_clock(const clockid_t which_clock){	int error = 0;	struct task_struct *p;	const pid_t pid = CPUCLOCK_PID(which_clock);	if (CPUCLOCK_WHICH(which_clock) >= CPUCLOCK_MAX)		return -EINVAL;	if (pid == 0)		return 0;	read_lock(&tasklist_lock);	p = find_task_by_pid(pid);	if (!p || (CPUCLOCK_PERTHREAD(which_clock) ?		   p->tgid != current->tgid : p->tgid != pid)) {		error = -EINVAL;	}	read_unlock(&tasklist_lock);	return error;}static inline union cpu_time_counttimespec_to_sample(const clockid_t which_clock, const struct timespec *tp){	union cpu_time_count ret;	ret.sched = 0;		/* high half always zero when .cpu used */	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {		ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;	} else {		ret.cpu = timespec_to_cputime(tp);	}	return ret;}static void sample_to_timespec(const clockid_t which_clock,			       union cpu_time_count cpu,			       struct timespec *tp){	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {		tp->tv_sec = div_long_long_rem(cpu.sched,					       NSEC_PER_SEC, &tp->tv_nsec);	} else {		cputime_to_timespec(cpu.cpu, tp);	}}static inline int cpu_time_before(const clockid_t which_clock,				  union cpu_time_count now,				  union cpu_time_count then){	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {		return now.sched < then.sched;	}  else {		return cputime_lt(now.cpu, then.cpu);	}}static inline void cpu_time_add(const clockid_t which_clock,				union cpu_time_count *acc,			        union cpu_time_count val){	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {		acc->sched += val.sched;	}  else {		acc->cpu = cputime_add(acc->cpu, val.cpu);	}}static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock,						union cpu_time_count a,						union cpu_time_count b){	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {		a.sched -= b.sched;	}  else {		a.cpu = cputime_sub(a.cpu, b.cpu);	}	return a;}/* * Divide and limit the result to res >= 1 * * This is necessary to prevent signal delivery starvation, when the result of * the division would be rounded down to 0. */static inline cputime_t cputime_div_non_zero(cputime_t time, unsigned long div){	cputime_t res = cputime_div(time, div);	return max_t(cputime_t, res, 1);}/* * Update expiry time from increment, and increase overrun count, * given the current clock sample. */static void bump_cpu_timer(struct k_itimer *timer,				  union cpu_time_count now){	int i;	if (timer->it.cpu.incr.sched == 0)		return;	if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {		unsigned long long delta, incr;		if (now.sched < timer->it.cpu.expires.sched)			return;		incr = timer->it.cpu.incr.sched;		delta = now.sched + incr - timer->it.cpu.expires.sched;		/* Don't use (incr*2 < delta), incr*2 might overflow. */		for (i = 0; incr < delta - incr; i++)			incr = incr << 1;		for (; i >= 0; incr >>= 1, i--) {			if (delta < incr)				continue;			timer->it.cpu.expires.sched += incr;			timer->it_overrun += 1 << i;			delta -= incr;		}	} else {		cputime_t delta, incr;		if (cputime_lt(now.cpu, timer->it.cpu.expires.cpu))			return;		incr = timer->it.cpu.incr.cpu;		delta = cputime_sub(cputime_add(now.cpu, incr),				    timer->it.cpu.expires.cpu);		/* Don't use (incr*2 < delta), incr*2 might overflow. */		for (i = 0; cputime_lt(incr, cputime_sub(delta, incr)); i++)			     incr = cputime_add(incr, incr);		for (; i >= 0; incr = cputime_halve(incr), i--) {			if (cputime_lt(delta, incr))				continue;			timer->it.cpu.expires.cpu =				cputime_add(timer->it.cpu.expires.cpu, incr);			timer->it_overrun += 1 << i;			delta = cputime_sub(delta, incr);		}	}}static inline cputime_t prof_ticks(struct task_struct *p){	return cputime_add(p->utime, p->stime);}static inline cputime_t virt_ticks(struct task_struct *p){	return p->utime;}static inline unsigned long long sched_ns(struct task_struct *p){	return (p == current) ? current_sched_time(p) : p->sched_time;}int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp){	int error = check_clock(which_clock);	if (!error) {		tp->tv_sec = 0;		tp->tv_nsec = ((NSEC_PER_SEC + HZ - 1) / HZ);		if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {			/*			 * If sched_clock is using a cycle counter, we			 * don't have any idea of its true resolution			 * exported, but it is much more than 1s/HZ.			 */			tp->tv_nsec = 1;		}	}	return error;}int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp){	/*	 * You can never reset a CPU clock, but we check for other errors	 * in the call before failing with EPERM.	 */	int error = check_clock(which_clock);	if (error == 0) {		error = -EPERM;	}	return error;}/* * Sample a per-thread clock for the given task. */static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,			    union cpu_time_count *cpu){	switch (CPUCLOCK_WHICH(which_clock)) {	default:		return -EINVAL;	case CPUCLOCK_PROF:		cpu->cpu = prof_ticks(p);		break;	case CPUCLOCK_VIRT:		cpu->cpu = virt_ticks(p);		break;	case CPUCLOCK_SCHED:		cpu->sched = sched_ns(p);		break;	}	return 0;}/* * Sample a process (thread group) clock for the given group_leader task. * Must be called with tasklist_lock held for reading. * Must be called with tasklist_lock held for reading, and p->sighand->siglock. */static int cpu_clock_sample_group_locked(unsigned int clock_idx,					 struct task_struct *p,					 union cpu_time_count *cpu){	struct task_struct *t = p; 	switch (clock_idx) {	default:		return -EINVAL;	case CPUCLOCK_PROF:		cpu->cpu = cputime_add(p->signal->utime, p->signal->stime);		do {			cpu->cpu = cputime_add(cpu->cpu, prof_ticks(t));			t = next_thread(t);		} while (t != p);		break;	case CPUCLOCK_VIRT:		cpu->cpu = p->signal->utime;		do {			cpu->cpu = cputime_add(cpu->cpu, virt_ticks(t));			t = next_thread(t);		} while (t != p);		break;	case CPUCLOCK_SCHED:		cpu->sched = p->signal->sched_time;		/* Add in each other live thread.  */		while ((t = next_thread(t)) != p) {			cpu->sched += t->sched_time;		}		cpu->sched += sched_ns(p);		break;	}	return 0;}/* * Sample a process (thread group) clock for the given group_leader task. * Must be called with tasklist_lock held for reading. */static int cpu_clock_sample_group(const clockid_t which_clock,				  struct task_struct *p,				  union cpu_time_count *cpu){	int ret;	unsigned long flags;	spin_lock_irqsave(&p->sighand->siglock, flags);	ret = cpu_clock_sample_group_locked(CPUCLOCK_WHICH(which_clock), p,					    cpu);	spin_unlock_irqrestore(&p->sighand->siglock, flags);	return ret;}int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp){	const pid_t pid = CPUCLOCK_PID(which_clock);	int error = -EINVAL;	union cpu_time_count rtn;	if (pid == 0) {		/*		 * Special case constant value for our own clocks.		 * We don't have to do any lookup to find ourselves.		 */		if (CPUCLOCK_PERTHREAD(which_clock)) {			/*			 * Sampling just ourselves we can do with no locking.			 */			error = cpu_clock_sample(which_clock,						 current, &rtn);		} else {			read_lock(&tasklist_lock);			error = cpu_clock_sample_group(which_clock,						       current, &rtn);			read_unlock(&tasklist_lock);		}	} else {		/*		 * Find the given PID, and validate that the caller		 * should be able to see it.		 */		struct task_struct *p;		rcu_read_lock();		p = find_task_by_pid(pid);		if (p) {			if (CPUCLOCK_PERTHREAD(which_clock)) {				if (p->tgid == current->tgid) {					error = cpu_clock_sample(which_clock,								 p, &rtn);				}			} else {				read_lock(&tasklist_lock);				if (p->tgid == pid && p->signal) {					error =					    cpu_clock_sample_group(which_clock,							           p, &rtn);				}				read_unlock(&tasklist_lock);			}		}		rcu_read_unlock();	}	if (error)		return error;	sample_to_timespec(which_clock, rtn, tp);	return 0;}/* * Validate the clockid_t for a new CPU-clock timer, and initialize the timer. * This is called from sys_timer_create with the new timer already locked. */int posix_cpu_timer_create(struct k_itimer *new_timer){	int ret = 0;	const pid_t pid = CPUCLOCK_PID(new_timer->it_clock);	struct task_struct *p;	if (CPUCLOCK_WHICH(new_timer->it_clock) >= CPUCLOCK_MAX)		return -EINVAL;	INIT_LIST_HEAD(&new_timer->it.cpu.entry);	new_timer->it.cpu.incr.sched = 0;	new_timer->it.cpu.expires.sched = 0;	read_lock(&tasklist_lock);	if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {		if (pid == 0) {			p = current;		} else {			p = find_task_by_pid(pid);			if (p && p->tgid != current->tgid)				p = NULL;		}	} else {		if (pid == 0) {			p = current->group_leader;		} else {			p = find_task_by_pid(pid);			if (p && p->tgid != pid)				p = NULL;		}	}	new_timer->it.cpu.task = p;	if (p) {		get_task_struct(p);	} else {		ret = -EINVAL;	}	read_unlock(&tasklist_lock);	return ret;}/* * Clean up a CPU-clock timer that is about to be destroyed. * This is called from timer deletion with the timer already locked. * If we return TIMER_RETRY, it's necessary to release the timer's lock * and try again.  (This happens when the timer is in the middle of firing.) */int posix_cpu_timer_del(struct k_itimer *timer){	struct task_struct *p = timer->it.cpu.task;	int ret = 0;	if (likely(p != NULL)) {		read_lock(&tasklist_lock);		if (unlikely(p->signal == NULL)) {			/*			 * We raced with the reaping of the task.			 * The deletion should have cleared us off the list.			 */			BUG_ON(!list_empty(&timer->it.cpu.entry));		} else {			spin_lock(&p->sighand->siglock);			if (timer->it.cpu.firing)				ret = TIMER_RETRY;			else				list_del(&timer->it.cpu.entry);			spin_unlock(&p->sighand->siglock);		}		read_unlock(&tasklist_lock);		if (!ret)			put_task_struct(p);	}	return ret;}/* * Clean out CPU timers still ticking when a thread exited.  The task * pointer is cleared, and the expiry time is replaced with the residual * time for later timer_gettime calls to return. * This must be called with the siglock held. */static void cleanup_timers(struct list_head *head,			   cputime_t utime, cputime_t stime,			   unsigned long long sched_time){	struct cpu_timer_list *timer, *next;	cputime_t ptime = cputime_add(utime, stime);	list_for_each_entry_safe(timer, next, head, entry) {		list_del_init(&timer->entry);		if (cputime_lt(timer->expires.cpu, ptime)) {			timer->expires.cpu = cputime_zero;		} else {			timer->expires.cpu = cputime_sub(timer->expires.cpu,							 ptime);		}	}	++head;	list_for_each_entry_safe(timer, next, head, entry) {		list_del_init(&timer->entry);		if (cputime_lt(timer->expires.cpu, utime)) {			timer->expires.cpu = cputime_zero;		} else {			timer->expires.cpu = cputime_sub(timer->expires.cpu,							 utime);		}	}	++head;	list_for_each_entry_safe(timer, next, head, entry) {		list_del_init(&timer->entry);		if (timer->expires.sched < sched_time) {			timer->expires.sched = 0;		} else {			timer->expires.sched -= sched_time;		}	}}/* * These are both called with the siglock held, when the current thread * is being reaped.  When the final (leader) thread in the group is reaped, * posix_cpu_timers_exit_group will be called after posix_cpu_timers_exit. */void posix_cpu_timers_exit(struct task_struct *tsk){	cleanup_timers(tsk->cpu_timers,		       tsk->utime, tsk->stime, tsk->sched_time);}void posix_cpu_timers_exit_group(struct task_struct *tsk){	cleanup_timers(tsk->signal->cpu_timers,		       cputime_add(tsk->utime, tsk->signal->utime),		       cputime_add(tsk->stime, tsk->signal->stime),		       tsk->sched_time + tsk->signal->sched_time);}/* * Set the expiry times of all the threads in the process so one of them * will go off before the process cumulative expiry total is reached. */static void process_timer_rebalance(struct task_struct *p,				    unsigned int clock_idx,				    union cpu_time_count expires,				    union cpu_time_count val){	cputime_t ticks, left;	unsigned long long ns, nsleft; 	struct task_struct *t = p;	unsigned int nthreads = atomic_read(&p->signal->live);	if (!nthreads)		return;	switch (clock_idx) {	default:		BUG();		break;	case CPUCLOCK_PROF:		left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),				       nthreads);		do {			if (likely(!(t->flags & PF_EXITING))) {				ticks = cputime_add(prof_ticks(t), left);				if (cputime_eq(t->it_prof_expires,					       cputime_zero) ||				    cputime_gt(t->it_prof_expires, ticks)) {					t->it_prof_expires = ticks;				}			}			t = next_thread(t);		} while (t != p);		break;	case CPUCLOCK_VIRT:		left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),				       nthreads);		do {			if (likely(!(t->flags & PF_EXITING))) {				ticks = cputime_add(virt_ticks(t), left);				if (cputime_eq(t->it_virt_expires,					       cputime_zero) ||				    cputime_gt(t->it_virt_expires, ticks)) {					t->it_virt_expires = ticks;				}			}			t = next_thread(t);		} while (t != p);		break;	case CPUCLOCK_SCHED:		nsleft = expires.sched - val.sched;		do_div(nsleft, nthreads);		nsleft = max_t(unsigned long long, nsleft, 1);		do {			if (likely(!(t->flags & PF_EXITING))) {				ns = t->sched_time + nsleft;				if (t->it_sched_expires == 0 ||				    t->it_sched_expires > ns) {					t->it_sched_expires = ns;				}			}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩三级视频中文字幕| 久久久99久久| 看电视剧不卡顿的网站| 91麻豆精品国产91久久久久| 美女视频黄久久| 欧美精品一区二区三区在线播放| 国产美女精品人人做人人爽| 国产欧美精品一区| 91猫先生在线| 午夜精品久久久久久久99樱桃| 91精品欧美综合在线观看最新| 老司机精品视频线观看86| 久久嫩草精品久久久精品一| 99国产精品一区| 日韩高清不卡一区| 国产欧美一区二区三区鸳鸯浴| 99久久国产综合精品色伊| 亚洲电影一级片| 久久综合九色综合欧美98| 99re这里只有精品6| 亚洲午夜久久久久久久久久久| 欧美一级在线免费| 懂色中文一区二区在线播放| 亚洲免费在线观看| 日韩三区在线观看| a亚洲天堂av| 丝瓜av网站精品一区二区| 久久久蜜桃精品| 在线观看视频欧美| 国产制服丝袜一区| 亚洲精品乱码久久久久久黑人 | 91成人看片片| 蜜桃视频第一区免费观看| 中文字幕欧美激情| 欧美日韩精品一区二区| 国产一区在线观看麻豆| 亚洲欧美日韩人成在线播放| 日韩一级高清毛片| 99综合电影在线视频| 日韩精品欧美精品| 国产精品美女久久福利网站| 337p亚洲精品色噜噜狠狠| 成人国产精品免费观看| 偷拍一区二区三区四区| 国产精品毛片久久久久久| 欧美日本一区二区在线观看| 国产ts人妖一区二区| 偷拍自拍另类欧美| 成人欧美一区二区三区在线播放| 91精品国产免费| 一本色道久久综合亚洲aⅴ蜜桃 | 国产一区二区三区电影在线观看| 一区二区三区在线免费播放| 久久综合九色综合97婷婷女人 | 日韩中文字幕不卡| 中文一区一区三区高中清不卡| 欧美美女直播网站| www.av精品| 久久99日本精品| 亚洲成人资源网| |精品福利一区二区三区| 精品国产一区二区亚洲人成毛片| 色88888久久久久久影院野外| 国产一区三区三区| 日韩国产高清影视| 亚洲美女视频在线| 国产三级精品在线| 精品久久久久久无| 欧美日韩国产免费一区二区| av电影在线观看一区| 国产做a爰片久久毛片| 三级一区在线视频先锋 | 在线看国产一区| 丁香五精品蜜臀久久久久99网站| 久久99久久久久| 午夜国产精品一区| 亚洲欧美日韩在线不卡| 欧美韩国日本一区| 久久久久国产精品厨房| 欧美一级日韩不卡播放免费| 欧美色网一区二区| 色悠悠久久综合| 97精品国产露脸对白| 成人午夜视频网站| 大桥未久av一区二区三区中文| 久久国产精品区| 免费观看久久久4p| 秋霞av亚洲一区二区三| 午夜日韩在线电影| 亚洲国产日产av| 亚洲国产精品久久久久婷婷884 | 九九精品一区二区| 奇米精品一区二区三区四区| 天天免费综合色| 日日夜夜免费精品| 视频一区二区中文字幕| 丝袜美腿亚洲色图| 日日夜夜精品视频天天综合网| 五月综合激情日本mⅴ| 亚洲一级二级在线| 亚洲一区二区三区不卡国产欧美| 夜夜爽夜夜爽精品视频| 亚洲精品五月天| 一区二区高清视频在线观看| 亚洲精品菠萝久久久久久久| 亚洲精品视频在线观看免费| 综合久久久久久| 亚洲欧美视频一区| 一区二区三区精品| 午夜久久电影网| 日韩极品在线观看| 日本午夜精品视频在线观看| 奇米一区二区三区av| 免费在线观看不卡| 久久国产精品免费| 国产乱理伦片在线观看夜一区| 国产盗摄女厕一区二区三区| 成人免费福利片| 色诱视频网站一区| 欧美嫩在线观看| 日韩精品一区二区三区在线| 26uuu欧美日本| 国产精品欧美一区喷水| 亚洲精品成人在线| 婷婷久久综合九色国产成人| 天天综合色天天综合色h| 免费在线视频一区| 国产成人午夜99999| av一区二区不卡| 欧美视频精品在线| 日韩欧美中文字幕精品| 久久九九久久九九| 亚洲丝袜制服诱惑| 亚洲国产精品一区二区久久恐怖片| 天堂av在线一区| 国产曰批免费观看久久久| yourporn久久国产精品| 欧美天堂亚洲电影院在线播放| 日韩欧美亚洲一区二区| 久久精品欧美一区二区三区不卡| 中文字幕一区二区视频| 香蕉成人伊视频在线观看| 韩国精品久久久| 91首页免费视频| 91精品国产入口| 久久久99精品久久| 一区二区三区在线视频观看| 蜜桃精品视频在线| av在线播放成人| 欧美一区二区在线视频| 国产日韩精品久久久| 一区二区三区精品在线观看| 蓝色福利精品导航| caoporm超碰国产精品| 91麻豆精品久久久久蜜臀| 国产欧美日本一区二区三区| 亚洲激情一二三区| 国内一区二区视频| 91国产精品成人| 精品国产精品网麻豆系列| 中文字幕一区二区三区精华液 | 99免费精品在线观看| 在线电影院国产精品| 国产日韩欧美一区二区三区乱码| 亚洲一区在线观看免费| 国产精品综合在线视频| 在线视频欧美区| 国产三级精品三级| 手机精品视频在线观看| eeuss鲁片一区二区三区在线看| 欧美一区二区精美| 国产精品福利一区二区三区| 日韩黄色片在线观看| 成人激情小说网站| 日韩免费观看2025年上映的电影| 亚洲男同性视频| 国产一区二区三区免费| 欧美色网站导航| 中文字幕av免费专区久久| 日韩国产欧美三级| 色综合天天综合网天天狠天天| 精品电影一区二区| 午夜精品福利在线| 99re6这里只有精品视频在线观看| 欧美成人video| 亚洲成人动漫一区| 91同城在线观看| 久久久欧美精品sm网站| 午夜av区久久| 色国产精品一区在线观看| 久久久欧美精品sm网站| 日本不卡123| 欧美视频一区二区三区| 中文字幕日韩一区二区| 国产精品影视网| 日韩视频中午一区| 亚洲成a人v欧美综合天堂下载| jizz一区二区| 日本一区二区三区免费乱视频| 免费视频一区二区|