void obstack_grow (struct obstack *obstack-ptr, void *data, int size)
让这部分空间变大(size 可以为负,那就是变小,但不会缩过头 @@),为了方便字符串等等数据类型
可以使用下面系列函数
void obstack_grow0 (struct obstack *obstack-ptr, void *data, int size)
void obstack_1grow (struct obstack *obstack-ptr, char c)
void obstack_ptr_grow (struct obstack *obstack-ptr, void *data)
void obstack_int_grow (struct obstack *obstack-ptr, int data)
grow 完了最后要 finish 一下
void * obstack_finish (struct obstack *obstack-ptr)
可以在 finish 之前测一下这个家伙有多大
int obstack_object_size (struct obstack *obstack-ptr)
不过因为这样做每 grow 一点都会检查是否需要分配新的 chunk 因此较慢,当有连续的
grow 产生而对 chunk 的把握正确的时候可以用对应的 fast grow 系列函数,如
void obstack_1grow_fast (struct obstack *obstack-ptr, char c)
void obstack_blank_fast (struct obstack *obstack-ptr, int size)
为了方便之前检查 chunk 剩余空间是否够用可以用
int obstack_room (struct obstack *obstack-ptr)
下面是一些其他的与 obstack 函数
void * obstack_base (struct obstack *obstack-ptr)
返回下一个 object 的地址(栈顶),如果有 growing object 则是该 object 地址。
如果需要进行对齐,下面的 macro 设置其掩膜
int obstack_alignment_mask (struct obstack *obstack-ptr)
使用类似设置 chunk size。
11. 一些 macro 调用的问题
obstack 是在老的 C 编译器上可能不好正常工作,特别是对利用 maco 产生了重定义的函数不能取址
但是遵循 ISO C 编译器可以,但是不保证在使用宏调用时参数会被多次利用产生的后果,如
obstack_alloc (get_obstack (), 4);
中 get_obstack () 或者 *obstack_list_ptr++ 这类参数。但是 GNU C 下这类参数不会被多次展开。
12. 可变大小自动释放类型,一个是 BSD extension,在 stdlib.h 中定义,使用 alloca 分配的
int
open2 (char *str1, char *str2, int flags, int mode)
{
char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
这样一个好处在于 longjmp() 时不需要再手工释放这部分内存。并且使用 alloca 分配的内存是
统一管理,不会造成内存碎片化。但是非 GNU 系统可能不支持,如果分配的内存太大会使程序崩溃
另外,还可以用 GCC 的方式:
int open2 (char *str1, char *str2, int flags, int mode)
{
char name[strlen (str1) + strlen (str2) + 1];
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
两种方式并不相同,后者可能仍然在栈内分配的内存,因此作用域结束即释放,而前者在程序结束
才释放。前者可用于循环体内,后者不可。
13. brk() 和 sbrk() 用于调整 data segment 的 high end,有什么用?
int brk (void *addr)
int sbrk (ptrdiff_t delta)
名字由来是原来进程里面 data segment 和 stack 对着干,一个从上向下长,一个从下向上长
中间隔开它们的是 break -.-b
14. root 可以调用一些相关函数将某个 page 锁住,这样不能被 paged out,目的是避免交换出去
造成再读入的开销。相关函数在 sys/mmem.h
int mlock (const void *addr, size_t len)
int munlock (const void *addr, size_t len)
int mlockall (int flags)
int munlockall (void)
这些是 POSIX.1b 的标准。
![nixsky[www.nixsky.com]](/templets/images/toplogo.gif)

