android lk解读 (4)---线程的等待执行

接下里的函数

void bs_set_timestamp(enum bs_entry bs_id)
{
	addr_t bs_imem = get_bs_info_addr();
	uint32_t clk_count = 0;

	if(bs_imem) {
		if (bs_id >= BS_MAX) {
			dprintf(CRITICAL, "bad bs id: %u, max: %u\n", bs_id, BS_MAX);
			ASSERT(0);
		}

		if (bs_id == BS_KERNEL_LOAD_START) {
			kernel_load_start = platform_get_sclk_count();
			return;
		}

		if(bs_id == BS_KERNEL_LOAD_DONE){
			clk_count = platform_get_sclk_count();
			if(clk_count){
				writel(clk_count - kernel_load_start,
					bs_imem + (sizeof(uint32_t) * BS_KERNEL_LOAD_TIME));
			}
		}
		else{
			clk_count = platform_get_sclk_count();
			if(clk_count){
				writel(clk_count,
					bs_imem + (sizeof(uint32_t) * bs_id));
			}
		}
	}
}
这个函数不干啥事

接下来的函数很牛

extern void *__ctor_list;
extern void *__ctor_end;
static void call_constructors(void)
{
	void **ctor;

	ctor = &__ctor_list;
	while(ctor != &__ctor_end) {
		void (*func)(void);

		func = (void (*)())*ctor;

		func();
		ctor++;
	}
}
这个才是c语言的精华所在,首先__ctor_list已经是一个void类型指针,取指针的地址当然要用**才行。然后 (void (*)( )) ,是一个返回值为void,参数为空的函数指针原型。

void heap_init(void)
{
	LTRACE_ENTRY;

	// set the heap range
	theheap.base = (void *)HEAP_START;    //这么做是方便以后这个base可以转换成任何类型的指针
//struct free_heap_chunk *chunk = (struct free_heap_chunk *)ptr;
	theheap.len = HEAP_LEN;

	LTRACEF("base %p size %zd bytes\n", theheap.base, theheap.len);

	// initialize the free list
	list_initialize(&theheap.free_list);

	// create an initial free chunk
	heap_insert_free_chunk(heap_create_free_chunk(theheap.base, theheap.len));

	// dump heap info
//	heap_dump();

//	dprintf(INFO, "running heap tests\n");
//	heap_test();
}
接下来看

#define __stack_chk_guard_setup() do { __stack_chk_guard = get_canary(); } while(0)
经典的宏定义,内核之中比比皆是啊

还有一个很经典的

static event_t dpc_event;

static int dpc_thread_routine(void *arg);

void dpc_init(void)
{
	event_init(&dpc_event, false, 0);   //初始化event

	thread_resume(thread_create("dpc", &dpc_thread_routine, NULL, DPC_PRIORITY, DEFAULT_STACK_SIZE));  //跑一个线程
}

status_t dpc_queue(dpc_callback cb, void *arg, uint flags)  //被别人调用
{
	struct dpc *dpc;

	dpc = malloc(sizeof(struct dpc));

	dpc->cb = cb;
	dpc->arg = arg;
	enter_critical_section();
	list_add_tail(&dpc_list, &dpc->node);
	event_signal(&dpc_event, (flags & DPC_FLAG_NORESCHED) ? false : true);   
	exit_critical_section();

	return NO_ERROR;
}

static int dpc_thread_routine(void *arg)
{
	for (;;) {
		event_wait(&dpc_event);   //等待event发生

		enter_critical_section();
		struct dpc *dpc = list_remove_head_type(&dpc_list, struct dpc, node);
		if (!dpc)
			event_unsignal(&dpc_event);
		exit_critical_section();

		if (dpc) {
//			dprintf("dpc calling %p, arg %p\n", dpc->cb, dpc->arg);
			dpc->cb(dpc->arg);

			free(dpc);
		}
	}

	return 0;
}
看看

status_t event_wait_timeout(event_t *e, time_t timeout)
{
	status_t ret = NO_ERROR;

	enter_critical_section();

#if EVENT_CHECK
	ASSERT(e->magic == EVENT_MAGIC);
#endif

	if (e->signalled) {
		/* signalled, we're going to fall through */
		if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) {   //如果flag是1则将signalled设为false
			/* autounsignal flag lets one thread fall through before unsignalling */
			e->signalled = false;
		}
	} else {
		/* unsignalled, block here */
		ret = wait_queue_block(&e->wait, timeout);  //不然就继续等待
		if (ret < 0)
			goto err;
	}

err:
	exit_critical_section();

	return ret;
}

还有

status_t event_signal(event_t *e, bool reschedule)
{
	enter_critical_section();

#if EVENT_CHECK
	ASSERT(e->magic == EVENT_MAGIC);
#endif

	if (!e->signalled) {  //init的时候signal是false,所以跑进来了
		if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) {   //<span style="font-family: Helvetica, Tahoma, Arial, sans-serif;">EVENT_FLAG_AUTOUNSIGNAL是1,所以跑不进来</span>
			/* try to release one thread and leave unsignalled if successful */
			if (wait_queue_wake_one(&e->wait, reschedule, NO_ERROR) <= 0) {
				/*
				 * if we didn't actually find a thread to wake up, go to
				 * signalled state and let the next call to event_wait
				 * unsignal the event.
				 */
				e->signalled = true;
			}
		} else {
			/* release all threads and remain signalled */
			e->signalled = true;   //让signal变成true
			wait_queue_wake_all(&e->wait, reschedule, NO_ERROR);
		}
	}

	exit_critical_section();

	return NO_ERROR;
}   //这个函数执行完之后signalled肯定变成true,所以event_wait(&dpc_event);里的才能执行而不是始终阻塞










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值