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

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

?? dpm.c

?? 一段基于linux的電源管理的源代碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * drivers/dpm/policy.c  Dynamic Power Management Policies * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002, International Business Machines Corporation * All Rights Reserved * * Robert Paulsen * IBM Linux Technology Center * rpaulsen@us.ibm.com * August, 2002 * *//* TODO:   Rethink init/enable/disable: It may be redundant and/or unsafe   Fix initialization and stats*/#include <linux/dpm.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/module.h>#include <linux/proc_fs.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <linux/trace.h>#include <asm/semaphore.h>#include <asm/system.h>#include <asm/uaccess.h>// debug printout// #define TRACE 1#undef TRACE#if defined(TRACE)#define trace(args...) do { printk("TRACE: "); printk(args); } while(0)#else#define trace(args...) do {} while(0)#endif#define DPM_PP_SIZE (DPM_PP_NBR * sizeof(dpm_md_pp_t))/****************************************************************************DPM Synchronization and Operating Point Changes===============================================There are 2 aspects to synchronization in DPM: First, the usual requirement ofserializing access to shared data structures, and second, the idea ofsynchronizing the operating point and the current operating state.  The secondcondition arises because setting an operating point may complete asynchronouslyfor a number of reasons, whereas the operating state change that causes theoperating point change succeeds immediately.Access to most of the global variables representing the current state of DPMand the current policy are protected by a spinlock, dpm_policy_lock.  The useof this lock appears in only a few critical places.Setting the operating point, reading the value of the current operating pointor changing the current policy may only be done while holding the semaphoredpm_sem.  Access to the dpm_sem is abstracted by the dpm_lock() anddpm_unlock() calls as explained below.  (The semaphore should only be accessedthis way to simplify future development).The dpm_sem must be held (by a call to a dpm_lock function) by any caller ofthe interfaces that set the operating point, change the policy, or enable ordisable DPM.  Note that the corresponding call to dpm_unlock() may beexplicitly required, or implicit (see dpm_set_opt_async() below).For simplicity, the calls that create operating points and policies also usedpm_lock() and dpm_unlock() to protect access to the non-active policies aswell. Since these are normally initialization calls, this should not interferewith the operation of the system once initialized.Three interfaces are provided for obtaining the dpm_sem:void dpm_lock();int dpm_lock_interruptible();int dpm_trylock();dpm_lock_interruptible() returns -ERESTARTSYS if the wait for the dpm_sem wasinterrupted, and dpm_trylock() returns -EBUSY if the semaphore is currentlyheld. Once the dpm_sem is held, two interfaces are provided for setting theoperating point:int dpm_set_opt_async()int dpm_set_opt_sync();Neither of these interfaces takes parameters since under DPM the operatingpoint to select is always implied by the current policy and operating state.If the system is already at the correct operating point then no change isrequired or made.  To avoid deadlock, the caller must not be holding thedpm_policy_lock when either of these calls is made.dpm_set_opt_async() launches a change in the operating point that willpotentially terminate asynchronously.  This interface never blocks the caller,thus there is no guarantee that the system is actually running at the impliedoperating point when control returns to the caller. This call is used bydpm_set_os() during an operating state change.  Note since this call terminatesasynchronously, the call to dpm_unlock() is implicitly made when the operatingpoint change is complete.  I.e., the caller obtains the dpm_sem withdpm_lock(), calls dpm_set_opt_async(), then continues.dpm_set_opt_sync() launches a synchronous change in the operating point.  Thiscall will block the caller as necessary during the call, thus it can only beissued from a process context.  When control returns to the caller, the callercan be sure that the implied operating point was set, and that the system iscurrently running at the correct operating point for the given policy andoperating state.  This call is used by dpm_set_policy() and the deviceconstraint update code to guarantee that the change to a new policy, or changesto operating point classes as a result of device constraits are reflected inthe operating point.Note that regardless of whether an operating point change is synchrounous orasynchronous, it is still possible that the operating state may change duringthe call.  Setting the operating point is (currently) not preemptible,therefore at the time that the operating point change is complete, it may nolonger be the correct operating point for the operating state.  This conditionis always handled by the dpm_set_opt*() routines, which will launch a taskletto re-synchronize the operating point to the operating state.It is possible that due to poorly designed policies and asynchronoustermination of operating point changes that the operating point will always lagbehind the operating state.  This is only a performance issue, not acorrectness issue.  Since a valid policy has a valid operating point for everyoperating state, and changes to the policy and changes in devices constraintsalways use dpm_set_opt_sync(), there will never be a case where the currentoperating point does not support device constraints.****************************************************************************//* curently installed policies, classes and operating points */LIST_HEAD(dpm_policies);LIST_HEAD(dpm_classes);LIST_HEAD(dpm_opts);DECLARE_MUTEX(dpm_sem);spinlock_t dpm_policy_lock = SPIN_LOCK_UNLOCKED;/* the currently active policy */struct dpm_policy *dpm_active_policy = 0;/* the currently active operating state and operating point */dpm_state_t dpm_active_state = DPM_NO_STATE;struct dpm_opt *dpm_active_opt = 0;/* is DPM initialized and enabled? */int dpm_enabled = 0;int dpm_initialized = 0;/***************************************************************************** * dpm_next_opt() returns the operating point that needs to be activated next, * or NULL if the operating point is up-to-date or the DPM system is disabled. * Since this call looks at the value of the current operating point, it can * only be made when the dpm_sem is held. *****************************************************************************/static inline struct dpm_opt *dpm_next_opt(void){	struct dpm_opt *opt = NULL;	unsigned long flags;	spin_lock_irqsave(&dpm_policy_lock, flags);	if (dpm_enabled) {		opt = dpm_active_policy->classes[dpm_active_state]->opt;		if (opt == dpm_active_opt)			opt = NULL;	}	spin_unlock_irqrestore(&dpm_policy_lock, flags);	return opt;}/***************************************************************************** * Set the operating point implied by the current DPM policy. These calls can * only be made while holding dpm_sem, and the release of * dpm_sem is implied by the call (see below). *****************************************************************************//***************************************************************************** * Set operating point asynchronously.  The dpm_sem will be cleared whenever * the change in operating point is complete. *****************************************************************************/intdpm_set_opt_async(void){	struct dpm_opt *opt = dpm_next_opt();	if (opt) {		dpm_trace(DPM_TRACE_SET_OPT_ASYNC, opt);		return dpm_md_set_opt(opt, DPM_UNLOCK);	} else {		dpm_trace(DPM_TRACE_SET_OPT_ASYNC, NULL);		dpm_unlock();		return 0;	}}/***************************************************************************** * Set operating point synchronously.  The caller must clear dpm_sem after the * call returns. *****************************************************************************/intdpm_set_opt_sync(void){	struct dpm_opt *opt = dpm_next_opt();	if (opt) {		dpm_trace(DPM_TRACE_SET_OPT_SYNC, opt);		return dpm_md_set_opt(opt, DPM_SYNC);	} else		dpm_trace(DPM_TRACE_SET_OPT_SYNC, NULL);	return 0;}/***************************************************************************** * Resynchronize the operating state and the operating point without * blocking. If we don't get the lock it doesn't matter, since whenever the * lock holder releases the lock the resynchronization will be tried again. *****************************************************************************/static inline voiddpm_resync(void){	dpm_trace(DPM_TRACE_RESYNC);	if (!dpm_trylock())		dpm_set_opt_async();}voiddpm_resync_task(unsigned long ignore){	dpm_resync();}/***************************************************************************** * unlock the DPM * * If the operating point and operating state are not in sync when dpm_sem is * released, a tasklet is launched to resynchronize them. A tasklet is used * rather than simply calling dpm_set_op directly to avoid deep recursions. * (I'm not sure this has worked, though). * * (The locking functions are inline in dpm_policy.h) * * This is not static since it needs to be called from dpm_policy.c *****************************************************************************/DECLARE_TASKLET(dpm_resync_tasklet, dpm_resync_task, 0);voiddpm_unlock(void){	int retry;	retry = dpm_next_opt() != NULL;	dpm_trace(DPM_TRACE_UNLOCK, retry);	up(&dpm_sem);	if (retry)		tasklet_schedule(&dpm_resync_tasklet);}/***************************************************************************** * Enter a new operating state for statistical purposes.  Returns 1 if the new * state may require a change in operating point and 0 otherwise. *  * The normal case that occurs during task scheduling, where we go from task * state to task state, is quickly ignored, as are changes to the * DPM_NO_STATE and changes when DPM is not running.  Otherwise, * dpm_enter_state() has advertised that we are in a new state, and indicates * whether an operating point change is required. *  * Note the system invariant that the operating point always eventually * catches up with changes to the operating state.  This is what makes it * correct here to check for common classes and operating points.  We know * that if a common operating point is not the current operating point, it * will be soon. * * The 'quick' variant (in dpm.h) is called out separately to reduce latency * for critical operating state changes where the following are known: 1) The * dpm_policy_lock is held and/or interrupts are properly disabled.  2) DPM is * enabled.  3) The new state is neither DPM_NO_STATE nor the same as the * active state.  4) Any operating point change is being handled elsewhere. *****************************************************************************/static intdpm_enter_state(int new_state){	int ret = 0;	unsigned long flags;	spin_lock_irqsave(&dpm_policy_lock, flags);        if ((new_state == dpm_active_state) ||             (new_state == DPM_NO_STATE) ||            !dpm_enabled) {		spin_unlock_irqrestore(&dpm_policy_lock, flags);		return ret;        }        if ((dpm_active_policy->classes[new_state] !=             dpm_active_policy->classes[dpm_active_state]) &&            (dpm_active_policy->classes[new_state]->opt !=             dpm_active_policy->classes[dpm_active_state]->opt))                ret = 1;	dpm_quick_enter_state(new_state);        spin_unlock_irqrestore(&dpm_policy_lock, flags);        return ret;}/***************************************************************************** * set operating state * * This is used by the kernel to inform the DPM that the operating state has * changed and that a new operating point should (possibly) be set as a * result. * * If an operating point change is required it is attempted. If we can't get * the lock here, then the operating point change will be activated when the * current lock holder releases the lock. *****************************************************************************/voiddpm_set_os(dpm_state_t new_state){	dpm_trace(DPM_TRACE_SET_OS, new_state);	TRACE_DPM(TRACE_EV_DPM_OS, new_state, NULL);	if (dpm_enter_state(new_state))		dpm_resync();}EXPORT_SYMBOL(dpm_set_os);/***************************************************************************** * initialize the DPM *****************************************************************************/intdpm_init(void){	trace("in dpm_init\n");	if (dpm_initialized) {		trace("DPM already initialized");		return -EALREADY;	}	/* mutex-style semaphore for access to policies, classes and opts */	init_MUTEX(&dpm_sem);	dpm_active_policy = 0;	/* this leaves the DPM temporarily				   disabled until a policy is				   activated */	dpm_enabled = 0;	dpm_initialized = 1;	dpm_active_state = DPM_TASK_STATE;	trace("DPM is now initialized\n");	return 0;}/***************************************************************************** * (temporarily) disable the DPM *****************************************************************************/intdpm_disable(void){	trace("in dpm_disable\n");	dpm_lock();	dpm_enabled = 0;	dpm_active_opt = NULL;	dpm_unlock();	trace("DPM is now disabled\n");	return 0;}/***************************************************************************** * re-enable the DPM * dpm_enabled = 1 implies that DPM is initialized and there is an active * policy. The 'enable' call is really designed to be used after a temporary * 'disable'.  All that's required to start DPM is to initialize it and set a * policy.  *****************************************************************************//* Need to think through enable/disable */intdpm_enable(void){	trace("in dpm_enable\n");	dpm_lock();	if (dpm_active_policy) {		dpm_enabled = 1;		mb();		dpm_set_opt_sync();		trace("DPM is now enabled\n");	} else {		trace("No active policy, dpm_enable is ignored\n");	}	dpm_unlock();	return 0;}/***************************************************************************** * Suspend/Resume DPM  * The current operating point is saved and restored. This * interface is designed to be used by system suspend/resume code, to safely * save/restore the DPM operating point across a system power-down, where the * firmware may resume the system at a random operating point.  This does not * require DPM to be enabled. Note that DPM remains locked across the * suspend/resume. *****************************************************************************/static struct dpm_opt suspend_opt = { name : "[Suspended Op. Point]" };struct dpm_opt *suspended_opt;intdpm_suspend(void){	int err;	trace("in dpm_suspend\n");	dpm_lock();	if (dpm_enabled && dpm_active_opt) {		suspended_opt = dpm_active_opt;	} else {		suspended_opt = &suspend_opt;		if ((err = dpm_md_get_opt(suspended_opt))) {			printk(KERN_CRIT 			       "DPM can not suspend the current op. point!\n");			suspended_opt = NULL;			return err;		}	}	return 0;}voiddpm_resume(void){	trace("in dpm_resume\n");	if (suspended_opt) {		dpm_active_opt = NULL;	/* Force reinitialization of DPM */		dpm_md_set_opt(suspended_opt, DPM_SYNC);		suspended_opt = NULL;	}	dpm_unlock();}/***************************************************************************** * Create a named operating point * The alternate entry point can be used to create anonymous operating points *****************************************************************************/int_dpm_create_opt(struct dpm_opt **p, const char *name, const dpm_md_pp_t * md_pp){	struct dpm_opt *opt;	int ret;	/* get memory for opt */	if (!	    (opt =	     (struct dpm_opt *) kmalloc(sizeof (struct dpm_opt), GFP_KERNEL))) {		return -ENOMEM;	}	trace("%s @ 0x%08lx\n", name, (unsigned long)opt);	memset(opt, 0, sizeof(struct dpm_opt));	if (!(opt->name = (char *) kmalloc(strlen(name) + 1, GFP_KERNEL))) {		kfree(opt);		return -ENOMEM;	}	/* initialize and validate the opt */	strcpy(opt->name, name);	memcpy(&opt->pp, md_pp, DPM_PP_SIZE);	ret = dpm_md_init_opt(opt);	if (ret) {		kfree(opt->name);		kfree(opt);		return ret;	}	INIT_LIST_HEAD(&opt->list);	*p = opt;	return 0;}intdpm_create_opt(const char *name, const dpm_md_pp_t * md_pp){	int ret;	struct dpm_opt *opt;	trace("in dpm_create_opt for \"%s\"\n", name);	dpm_lock();	/* ensure name is unique */	list_find(opt, name, dpm_opts, struct dpm_opt);	if (opt) {		dpm_unlock();		return -EEXIST;	}	/* create the opt */	ret = _dpm_create_opt(&opt, name, md_pp);	/* add opt to our list */	if (!ret)		list_add(&opt->list, &dpm_opts);	dpm_unlock();	return ret;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人黄色国产精品网站大全在线免费观看 | 国产成人精品一区二区三区四区| 91精品国产美女浴室洗澡无遮挡| 天堂久久久久va久久久久| 欧美网站一区二区| 日韩影视精彩在线| 精品国产一二三区| 国产黄人亚洲片| ...av二区三区久久精品| 日韩一级片在线观看| 裸体歌舞表演一区二区| 久久这里都是精品| 国产+成+人+亚洲欧洲自线| 中文字幕在线不卡一区| 色播五月激情综合网| 日韩在线播放一区二区| 久久久噜噜噜久噜久久综合| 成人白浆超碰人人人人| 亚洲一区在线观看免费观看电影高清 | 色哟哟日韩精品| 日韩国产成人精品| 国产三级三级三级精品8ⅰ区| 99视频一区二区| 亚洲二区在线观看| 2017欧美狠狠色| 91视视频在线观看入口直接观看www | 国产最新精品免费| 中文字幕乱码久久午夜不卡 | 制服丝袜av成人在线看| 国产精品乡下勾搭老头1| 亚洲欧美区自拍先锋| 日韩一级高清毛片| 91丨porny丨首页| 裸体健美xxxx欧美裸体表演| 亚洲国产精华液网站w| 欧美日韩国产美| 成人福利电影精品一区二区在线观看| 亚洲成av人影院| 国产精品欧美极品| 日韩欧美在线综合网| 91精品1区2区| 风流少妇一区二区| 日韩av一区二区在线影视| 国产精品福利影院| 欧美tickling挠脚心丨vk| 91黄色小视频| 成人sese在线| 久久精品国产秦先生| 亚洲韩国精品一区| 亚洲同性同志一二三专区| 久久久无码精品亚洲日韩按摩| 在线国产亚洲欧美| av欧美精品.com| 国产suv精品一区二区6| 毛片不卡一区二区| 香蕉乱码成人久久天堂爱免费| 国产精品毛片大码女人| 26uuu精品一区二区在线观看| 欧美精品 日韩| 欧美视频中文一区二区三区在线观看| 成人高清视频在线| 国产成人亚洲综合色影视| 九色|91porny| 六月婷婷色综合| 奇米影视一区二区三区| 午夜欧美一区二区三区在线播放| 伊人夜夜躁av伊人久久| 亚洲欧洲性图库| 国产精品精品国产色婷婷| 国产亚洲欧美中文| 久久久久久久综合日本| 久久亚区不卡日本| 久久亚洲精精品中文字幕早川悠里| 在线91免费看| 欧美一级xxx| 日韩午夜电影在线观看| 91精品国模一区二区三区| 欧美高清dvd| 制服丝袜亚洲播放| 日韩午夜在线播放| 精品国产一区二区亚洲人成毛片 | 一区二区三区四区中文字幕| 国产精品麻豆99久久久久久| 亚洲国产成人私人影院tom| 亚洲国产精品成人综合色在线婷婷| 国产拍揄自揄精品视频麻豆| 亚洲国产精品99久久久久久久久| 国产精品色一区二区三区| 中文字幕日本不卡| 亚洲综合一区在线| 午夜电影一区二区三区| 乱一区二区av| 国产精品中文字幕欧美| 成人动漫一区二区在线| 色偷偷久久一区二区三区| 欧美午夜精品一区二区三区| 欧美酷刑日本凌虐凌虐| 欧美成人a∨高清免费观看| 2023国产精品自拍| 国产精品欧美一区喷水| 一区二区三区精品视频在线| 三级不卡在线观看| 久草中文综合在线| 99这里只有精品| 欧美高清精品3d| 国产日本一区二区| 夜夜嗨av一区二区三区四季av| 日韩电影在线一区| 国产白丝网站精品污在线入口| 91香蕉国产在线观看软件| 欧美日韩精品欧美日韩精品一综合| 91精品国产91久久综合桃花| 久久久久久一级片| 亚洲精品国产高清久久伦理二区| 日本va欧美va欧美va精品| 国产99久久久久久免费看农村| 91高清在线观看| 精品国产一区二区三区不卡| 亚洲黄色尤物视频| 韩国三级中文字幕hd久久精品| 91丨九色丨黑人外教| 欧美大白屁股肥臀xxxxxx| 亚洲欧美在线视频观看| 免费一级欧美片在线观看| 91在线观看下载| 欧美成人bangbros| 一区二区欧美精品| 国产精品一区二区x88av| 欧美三日本三级三级在线播放| 精品国产百合女同互慰| 亚洲一区二区精品3399| 国产成人啪午夜精品网站男同| 欧美日韩精品二区第二页| 国产精品美女久久久久久久| 蜜桃91丨九色丨蝌蚪91桃色| 一本一道综合狠狠老| 久久天堂av综合合色蜜桃网| 五月天亚洲精品| 9i在线看片成人免费| 久久精品亚洲精品国产欧美| 婷婷久久综合九色国产成人 | 亚洲一卡二卡三卡四卡无卡久久 | 日韩视频在线一区二区| 一区二区三区四区在线播放 | 在线观看91精品国产麻豆| 中文字幕一区二区在线播放| 精品在线一区二区| 7777精品伊人久久久大香线蕉的 | 亚洲成a人片综合在线| 99精品国产99久久久久久白柏| xnxx国产精品| 日本亚洲免费观看| 欧美片在线播放| 亚洲国产你懂的| 色天使久久综合网天天| 亚洲欧洲国产日韩| 国产99精品视频| 久久久99久久| 国产呦萝稀缺另类资源| 精品欧美久久久| 美洲天堂一区二卡三卡四卡视频 | 欧美日本一区二区| 亚洲主播在线观看| 99久久婷婷国产精品综合| 国产精品理论片| 成人精品视频一区| 亚洲国产经典视频| va亚洲va日韩不卡在线观看| 国产日韩成人精品| 成人黄色免费短视频| 国产精品久久久爽爽爽麻豆色哟哟 | 欧美激情在线免费观看| 国产激情91久久精品导航| 国产亚洲综合性久久久影院| 国产精品亚洲一区二区三区妖精 | 亚洲已满18点击进入久久| 色综合中文字幕国产 | 色综合天天在线| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲免费高清视频在线| 色哟哟一区二区三区| 午夜久久电影网| 日韩视频一区在线观看| 精东粉嫩av免费一区二区三区| 欧美tickling挠脚心丨vk| 国产福利精品一区| 综合欧美一区二区三区| 在线观看成人免费视频| 亚洲狠狠爱一区二区三区| 欧美一级二级在线观看| 国产精品资源在线观看| 中文字幕不卡三区| 日本高清免费不卡视频| 天天操天天色综合| 欧美精品一区二区三区蜜臀| 国产99久久久国产精品| 艳妇臀荡乳欲伦亚洲一区| 欧美日韩成人综合在线一区二区| 麻豆精品国产传媒mv男同 | 日韩一区二区高清|