关闭

Event auto wakelock 介绍

标签: androidstructinputlistfilemodule
2328人阅读 评论(0) 收藏 举报
分类:

Evdev auto wakelock 介绍

介绍kernel-2.6.25 关于event 加锁的机制,从中窥探linux的锁机制。

kernel版本比较旧,对比2.6.32发现kernel在锁机制方面基本没变,但是在机制的实现上有很大的变化。

1.evdev模块初始化

module_init(evdev_init);


2.evdev初始化

static int __init evdev_init(void)
{
	return input_register_handler(&evdev_handler);
}


3.回调方法集定义

static struct input_handler evdev_handler = {
	.event		= evdev_event,
	.connect	= evdev_connect,
	.disconnect	= evdev_disconnect,
	.fops		= &evdev_fops,
	.minor		= EVDEV_MINOR_BASE,
	.name		= "evdev",
	.id_table	= evdev_ids,
};


4.event方法的实现函数

static void evdev_event(struct input_handle *handle,
			unsigned int type, unsigned int code, int value)
{
//...
	rcu_read_lock();
//...
	if (client)
		evdev_pass_event(client, &event);
	else
		list_for_each_entry_rcu(client, &evdev->client_list, node)
			evdev_pass_event(client, &event);
//...
	rcu_read_unlock();
//...
}


5.event发生时的处理,加锁了!获取evdev的超时锁,超时时间是5*HZ,HZ根据不同CPU而定,这里是50ms

static void evdev_pass_event(struct evdev_client *client,
			     struct input_event *event)
{
//...
#ifdef CONFIG_ANDROID_POWER
	android_lock_suspend_auto_expire(&client->suspend_lock, 5 * HZ); //50ms
#endif
//...
}


6.evdev节点打开方法的实现,初始化名为“evdev”的锁,锁的类型不在这里声明,在申请锁的时候才声明是超时锁还是非超时锁

static int evdev_open(struct inode *inode, struct file *file)
{
//...
#ifdef CONFIG_ANDROID_POWER
	client->suspend_lock.name = "evdev";
	android_init_suspend_lock(&client->suspend_lock);
#endif
//...
}
static int evdev_release(struct inode *inode, struct file *file)
{
//...
#ifdef CONFIG_ANDROID_POWER
	android_uninit_suspend_lock(&client->suspend_lock);
#endif
//...
}


7.申请超时锁的实现,把锁加入活跃数组。共有三种数组,这里是之一。

void android_lock_suspend_auto_expire(android_suspend_lock_t *lock, int timeout)
{
	unsigned long irqflags;
	spin_lock_irqsave(&g_list_lock, irqflags);
#ifdef CONFIG_ANDROID_POWER_STAT
	if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
		lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
		lock->stat.last_time = ktime_get();
	}
#endif
	if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
		printk(KERN_INFO "android_power: acquire wake lock: %s, "
			"timeout %d.%03lu\n", lock->name, timeout / HZ,
			(timeout % HZ) * MSEC_PER_SEC / HZ);
	lock->expires = jiffies + timeout;
	lock->flags |= ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
	list_del(&lock->link);
	list_add(&lock->link, &g_active_partial_wake_locks);
	g_current_event_num++;
	wake_up(&g_wait_queue);
	spin_unlock_irqrestore(&g_list_lock, irqflags);
}





2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:370208次
    • 积分:3409
    • 等级:
    • 排名:第10164名
    • 原创:48篇
    • 转载:16篇
    • 译文:2篇
    • 评论:35条
    最新评论