Android wakelock的申请和释放

Android wakelock可以被内核空间和用户空间 申请和释放。申请的是非超时锁,需要相应的调用wake_unlock来释放,而超时锁则不需要手工释放(当然你也可以手工释放),超时后kernel系统会自动释放锁

在内核空间可以直接调用wake_lock, wake_lock_timeout 申请锁

Android kernel为用户空间提供了申请和释放wakelock的接口,实现在kernel/power/userwakelock.c中,下面我们简单的分析下这个文件,userwakelock中仅仅涉及到用户空间操作的锁,所有锁通过红黑树进行管理,在这里就不对红黑树的操作进行分析了。

用户空间访问接口:

/sys/power/wake_lock

/sys/power/wake_unlock


129 ssize_t wake_lock_show(
130     struct kobject *kobj, struct kobj_attribute *attr, char *buf)
131 {
132     char *s = buf;
133     char *end = buf + PAGE_SIZE;
134     struct rb_node *n;
135     struct user_wake_lock *l;
136
137     mutex_lock(&tree_lock);
138
139     for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) {
140         l = rb_entry(n, struct user_wake_lock, node);
141         if (wake_lock_active(&l->wake_lock))
142             s += scnprintf(s, end - s, "%s ", l->name);
143     }
144     s += scnprintf(s, end - s, "\n");
145
146     mutex_unlock(&tree_lock);
147     return (s - buf);
148 }

显示应用空间申请的所有激活锁(包括超时锁和非超时锁)


150 ssize_t wake_lock_store(
151     struct kobject *kobj, struct kobj_attribute *attr,
152     const char *buf, size_t n)
153 {
154     long timeout;
155     struct user_wake_lock *l;
156
157     mutex_lock(&tree_lock);
158     l = lookup_wake_lock_name(buf, 1, &timeout);
159     if (IS_ERR(l)) {
160         n = PTR_ERR(l);
161         goto bad_name;
162     }
163
164     if (debug_mask & DEBUG_ACCESS)
165         pr_info("wake_lock_store: %s, timeout %ld\n", l->name, timeout);
166
167     if (timeout)
168         wake_lock_timeout(&l->wake_lock, timeout);
169     else
170         wake_lock(&l->wake_lock);
171 bad_name:
172     mutex_unlock(&tree_lock);
173     return n;
174 }

申请一把锁,名字以及超时时间都包含在参数@buf中,lookup_wake_lock_name会解析出名字和超时时间,如果超时时间不存在说明申请的是非超时锁,否则是超时锁


167~170 调用wake_lock申请非超时锁;调用wake_lock_timeout申请非超时锁。


177 ssize_t wake_unlock_show(
178     struct kobject *kobj, struct kobj_attribute *attr, char *buf)
179 {
180     char *s = buf;
181     char *end = buf + PAGE_SIZE;
182     struct rb_node *n;
183     struct user_wake_lock *l;
184
185     mutex_lock(&tree_lock);
186
187     for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) {
188         l = rb_entry(n, struct user_wake_lock, node);
189         if (!wake_lock_active(&l->wake_lock))
190             s += scnprintf(s, end - s, "%s ", l->name);
191     }
192     s += scnprintf(s, end - s, "\n");
193
194     mutex_unlock(&tree_lock);
195     return (s - buf);
196 }

该函数显示当前应用空间可申请的所有未激活锁(包括超时锁和非超时锁),打印出锁的名字,返回给用户空间。

187 遍历整个RB树,


198 ssize_t wake_unlock_store(
199     struct kobject *kobj, struct kobj_attribute *attr,
200     const char *buf, size_t n)
201 {
202     struct user_wake_lock *l;
203
204     mutex_lock(&tree_lock);
205     l = lookup_wake_lock_name(buf, 0, NULL);
206     if (IS_ERR(l)) {
207         n = PTR_ERR(l);
208         goto not_found;
209     }
210
211     if (debug_mask & DEBUG_ACCESS)
212         pr_info("wake_unlock_store: %s\n", l->name);
213
214     wake_unlock(&l->wake_lock);
215 not_found:
216     mutex_unlock(&tree_lock);
217     return n;
218 }


205 用户空间接口按照RB(红黑树)来组织wakelock锁,这样可以加快查找速度,第三个参数为NULL,因为wake_unlock_store仅仅针对非超时锁,超时锁不需要unlock

214 调用wake_unlock释放非超时锁



如果用命令

#echo "kaka 12" > /sys/power/wake_lock

申请一个超时锁,那么在超时后,执行

#cat /sys/power/wake_lock 

kaka

显示这个超时锁还存在,觉得这个接口有问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值