借助隐式初始化简化程序逻辑(z)
时间:2010-04-01 来源:huhfire
在图1中示例了三个API的原型,分别是mprotector_init()、mprotector_fini()和mprotector_section_add()。假设mprotector_section_add()将会被多个任务调用以用于初始化各任务相关的一些数据,但是在mprotector_section_add()被调用之前,必需保证mprotector_init()已经被执行过了且只能执行一次。此外,图中也示例了任务A和B分别在其入口函数中调用mprotector_section_add()以进行相应的操作。那现在的问题是,mprotector_init()应当放在什么地方被调用呢?显然,放到任务A和B的入口函数内不太好,这会造成一旦任务的初始化顺序或是优先级变了以后,结果就截然不同。很容易想到的另一种方法是,在创建任务A和B之前,先调用mprotector_init(),如此一来问题也就解决了。还有更好的方法吗?
example.c
int mprotector_init ();
int mprotector_fini ();
int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size);
void task_entry_A (void *_p_arg)
{
maddr_t start;
msize_t size;
...
mprotector_section_add (SECTION_1, start, size);
...
}
void task_entry_B (void *_p_arg)
{
maddr_t start;
msize_t size;
...
mprotector_section_add (SECTION_2, start, size);
...
}
int mprotector_init ();
int mprotector_fini ();
int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size);
void task_entry_A (void *_p_arg)
{
maddr_t start;
msize_t size;
...
mprotector_section_add (SECTION_1, start, size);
...
}
void task_entry_B (void *_p_arg)
{
maddr_t start;
msize_t size;
...
mprotector_section_add (SECTION_2, start, size);
...
}
图1
更好的方法是采用隐式初始化的方法,这需要对mprotector_init()和mprotector_section_add()两个函数做一些更改,如图2所示。mprotector_init()中的更改是允许它被多次调用,但在其中新增一个静态的局部变量用于记录是否已经被真正地初始化过了,当mprotector_init()发现这一变量变成了true以后,就直接返回0表示成功,否则需要进行后续的初始化操作。最后,在mprotector_section_add()中则需要增加对mprotector_init()的调用。
更好的方法是采用隐式初始化的方法,这需要对mprotector_init()和mprotector_section_add()两个函数做一些更改,如图2所示。mprotector_init()中的更改是允许它被多次调用,但在其中新增一个静态的局部变量用于记录是否已经被真正地初始化过了,当mprotector_init()发现这一变量变成了true以后,就直接返回0表示成功,否则需要进行后续的初始化操作。最后,在mprotector_section_add()中则需要增加对mprotector_init()的调用。
example.c
int mprotector_init ()
{
static bool initialized = false;
if (initialized) {
return 0;
}
...
initialized = true;
return 0;
}
int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size)
{
if (0 != mprotector_init ()) {
return -1;
}
...
}
int mprotector_init ()
{
static bool initialized = false;
if (initialized) {
return 0;
}
...
initialized = true;
return 0;
}
int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size)
{
if (0 != mprotector_init ()) {
return -1;
}
...
}
图2
有了这些更改以后,使用mprotector_section_add()函数的用户就根本不需要考虑在什么地方调用mprotector_init()函数,而这,也就简化了程序逻辑。
有了这些更改以后,使用mprotector_section_add()函数的用户就根本不需要考虑在什么地方调用mprotector_init()函数,而这,也就简化了程序逻辑。
相关阅读 更多 +