#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \ // 为了当x,y 是表达式的时候,编译报错如i++,j++; 或者是 x y 不是同一个类型 的时候,不同的指针比较编译警告。
_x < _y ? _x : _y; })
// android binder
struct binder_buffer {
struct list_head entry; /* free and allocated entries by address */
struct rb_node rb_node; /* free entry by size or allocated entry */
/* by address */
unsigned free:1;
unsigned allow_user_free:1;
unsigned async_transaction:1;
unsigned debug_id:29;
struct binder_transaction *transaction;
#ifdef BINDER_MONITOR
struct binder_transaction_log_entry *log_entry;
#endif
struct binder_node *target_node;
size_t data_size;
size_t offsets_size;
uint8_t data[0]; // 获得一个内存地址标记并可以节省不必要的存储空间
};
buffer = rb_entry(n, struct binder_buffer, rb_node);
tmp_size = binder_buffer_size(target_proc, buffer);// 计算 buffer 的容量大小。由于内存是线性增长分配的,并且在entry 中按地址排列,所以 由 下一个buffer 的地址- 这个buffer的data 就是 当前buffer大小。
static size_t binder_buffer_size(struct binder_proc *proc,
struct binder_buffer *buffer)
{
if (list_is_last(&buffer->entry, &proc->buffers))
//proc->buffer_size = vma->vm_end - vma->vm_start
return proc->buffer + proc->buffer_size - (void *)buffer->data;
else
return (size_t)list_entry(buffer->entry.next,
struct binder_buffer, entry) - (size_t)buffer->data;
}
// 位域,不是所有的编译器都支持这种用法,对于有些编译器一个位域不能跨字节,不够的话,从下个字节开始。
struct _a
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
};
struct _b
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}
// 红黑树的实现,红黑树通过着色保持到NULL 节点最长的路径最多是最短的路径两倍。以达到普通二叉树与平衡二叉树的折中选择。
着色只有红黑两种,可以用一位,来表示;tree_node 的三要素 parent ,child_left, child_right ,可以肯定
每个节点都有唯一的parent;看下面的 struct rb_node 是 (aligned(sizeof(long))) 对齐的;这样指向 parent node 的地址parent 两位最低权值的bit 位为00是确定的,没有有效的信息熵,可以用来承载rb_node 的color 信息。所以__rb_parent_color才会有下面 rb_parent 宏 ,以及rb_set_parent ,rb_set_parent_color 函数。
struct rb_node {
unsigned long __rb_parent_color;
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)
struct rb_root {
struct rb_node *rb_node;
};
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
}
static inline void rb_set_parent_color(struct rb_node *rb,
struct rb_node *p, int color)
{
rb->__rb_parent_color = (unsigned long)p | color;
}