探秘SensorHAL(八)

2014-11-24 07:30:28 · 作者: · 浏览: 9
tch (mode) {
case SENSOR_DESTROY:
goto exit;
case SENSOR_SLEEP:
pthread_mutex_lock(&worker->mode_mutex);
pthread_cond_wait(&worker->suspend_cond, &worker->mode_mutex);
pthread_mutex_unlock(&worker->mode_mutex);
break;
default:
worker->poll_callback(worker->arg);
break;
}
if (worker->delay_ns)
sensor_nano_sleep(worker->delay_ns);
}
exit:
return NULL;
}
这是一个工作线程,用来处理不同模式的不同动作,这些不同的模式由worker->mode来进行控制,同时worker->mode又由互斥锁worker->mode_mutex进行保护来防止读写冲突。此mode实际有三种:
SENSOR_SLEEP
SENSOR_RUNNING
SENSOR_DESTROY
分别对应三个工作函数:
sensors_worker_suspend
sensors_worker_resume
sensors_worker_destroy
这三个工作函数又在sensors_worker_init初始化时分别分配给了:
worker->suspend
worker->resume
worker->destroy
综上, sensors_worker_internal_worker中default即为SENSOR_RUNNING,其他状态暂不说明,先解决了这个RUNNING。在第一次初始化的时候默认给出的是SLEEP状态,则会等待suspend_cond变量,试看谁在使用这个变量。在sensors_worker.c中不难发现,在resume和destroy函数中,当前一状态为SLEEP时,会释放suspend_cond:
[cpp]
static void sensors_worker_resume(struct sensors_worker_t* worker)
{
enum sensors_worker_mode prev_mode;
pthread_mutex_lock(&worker->mode_mutex);
prev_mode = worker->mode;
worker->mode = SENSOR_RUNNING;
if (prev_mode == SENSOR_SLEEP)
pthread_cond_broadcast(&worker->suspend_cond);
pthread_mutex_unlock(&worker->mode_mutex);
}
static void sensors_worker_destroy(struct sensors_worker_t* worker)
{
enum sensors_worker_mode prev_mode;
pthread_mutex_lock(&worker->mode_mutex);
prev_mode = worker->mode;
worker->mode = SENSOR_DESTROY;
if (prev_mode == SENSOR_SLEEP)
pthread_cond_broadcast(&worker->suspend_cond);
pthread_mutex_unlock(&worker->mode_mutex);
pthread_join(worker->worker_thread_id, NULL);
}
两者不同之处在于,resume会让传感器的状态切换到RUNNING,而destroy会使其切换至DESTROY状态,从而导致线程sensors_worker_internal_worker退出,传感器工作停止。问题又来了,初始化的状态是SLEEP,什么时候?谁?来激活这个工作线程呢?问题的答案在bma150_input.c ( DASH/bma150_input.c ):
[cpp]
static int bma150_input_activate(struct sensor_api_t *s, int enable)
{
struct sensor_desc *d = container_of(s, struct sensor_desc, api);
int fd = d->select_worker.get_fd(&d->select_worker);
/* suspend/resume will be handled in kernel-space */
if (enable && (fd < 0)) {
fd = open_input_dev_by_name(BMA150_INPUT_NAME,
O_RDONLY | O_NONBLOCK);
if (fd < 0) {
ALOGE("%s: failed to open input dev %s\n", __func__,
BMA150_INPUT_NAME);
return -1;
}
d->select_worker.set_fd(&d->select_worker, fd);
d->select_worker.resume(&d->select_worker);
} else if (!enable && (fd > 0)) {
d->select_worker.set_fd(&d->select_worker, -1);
d->select_worker.suspend(&d->select_worker);
}
return 0;
}
前面只是一代而过activate函数,没有进行分析,回头来看,原来resume与suspend操作就在这里,当未初始化且要求开启时,寻找驱动句柄,并设置句柄,然后执行resume操作,从而使sensors_worker_internal_worker工作线程开启,执行worker->poll_callback函数。在回去之前还是把avtivate看完,除了上边说的开启的情况,就是关闭的情况。当驱