您的位置:首页 > 移动开发 > Android开发

Android内核源码bionic目录下的源码的学习笔记

2015-01-11 11:21 411 查看
好记性不如烂笔头。今天要做的学习是关于bionic目录下的代码。

首先需要看的是_errno.c这份代码。

volatile int*  __errno( void )
{
return  &((volatile int*)__get_tls())[TLS_SLOT_ERRNO];
}
从上面可以看出,返回的是一个指向int类型的指针。

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

volatile的本意是“易变的”,不过翻译成“直接存取原始内存地址”更为合适。“易变”是因为外在因素引起的,象多线程,中断等,并不是因为用volatile修饰了的变量就是“易变”了,假如没有外因,即使用volatile定义,它也不会变化。

第二个需要说到的_set_errono.c的这份代码。

这个函数最终会被系统进行调用。

同时在这个函数里面,即使数据超过边界,依旧不会认为是个错误。因为在Linux中,错误的编码不会超过131.

if(n > -256) {
return __set_errno(-n);
} else {
return n;
}


OpenBSD是一个多平台的,基于4.4BSD的类UNIX操作系统,是BSD衍生出的三种免费操作系统(另外两种是NetBSD和FreeBSD)之一,被称为世界上最安全的操作系统

接下来需要学习的是arc4random.c。

static pthread_mutex_t  _arc4_lock = PTHREAD_MUTEX_INITIALIZER;
#define  _ARC4_LOCK()      pthread_mutex_lock(&_arc4_lock)
#define  _ARC4_UNLOCK()    pthread_mutex_unlock(&_arc4_lock)


定义锁的作用是保护文件中的全局的变量。

只要注意这个文件是用来生成0~1之间的随机数就可以了。

接下来看一下basename.c这个类。

在这个文件中,仅仅存在一个函数,返回的是一个字符串。

if (bname == NULL) {
bname = (char *)malloc(MAXPATHLEN);
if (bname == NULL)
return(NULL);
}


很明显存在分配存储空间。

接下来看到的这个文件是bionic_clone这个文件。

主要查看里面的clone方法。

int
clone(int (*fn)(void *), void *child_stack, int flags, void*  arg, ...)
{
va_list  args;
int     *parent_tidptr = NULL;
void    *new_tls = NULL;
int     *child_tidptr = NULL;
int     ret;

/* extract optional parameters - they are cummulative */
va_start(args, arg);
if (flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID)) {
parent_tidptr = va_arg(args, int*);
}
if (flags & (CLONE_SETTLS|CLONE_CHILD_SETTID)) {
new_tls = va_arg(args, void*);
}
if (flags & CLONE_CHILD_SETTID) {
child_tidptr = va_arg(args, int*);
}
va_end(args);

ret = __bionic_clone(flags, child_stack, parent_tidptr, new_tls, child_tidptr, fn, arg);
return ret;
}


1、参数列表

2、父线程与子线程指针以及返回数值的定义。

接下来查看的文件是clearenv这个文件。

int clearenv(void)
{
char **P = environ;

if (P != NULL) {
for (; *P; ++P)
*P = NULL;
}
return 0;
}


由上面可以看出environ是一个纸箱指针的指针,也可以理解为是一个字符串的二维数组。

在dlmalloc文件中要注意下面的方法:

static size_t release_unused_segments(mstate m) {
size_t released = 0;
msegmentptr pred = &m->seg;
msegmentptr sp = pred->next;
while (sp != 0) {
char* base = sp->base;
size_t size = sp->size;
msegmentptr next = sp->next;
if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
mchunkptr p = align_as_chunk(base);
size_t psize = chunksize(p);
/* Can unmap if first chunk holds entire segment and not pinned */
if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
tchunkptr tp = (tchunkptr)p;
assert(segment_holds(sp, (char*)sp));
if (p == m->dv) {
m->dv = 0;
m->dvsize = 0;
}
else {
unlink_large_chunk(m, tp);
}
if (CALL_MUNMAP(base, size) == 0) {
released += size;
m->footprint -= size;
/* unlink obsoleted record */
sp = pred;
sp->next = next;
}
else { /* back out if cannot unmap */
insert_large_chunk(m, tp, psize);
}
}
}
pred = sp;
sp = next;
}
return released;
}


在pthread-timers中主要关注下面的一个结构体的定义:

struct thr_timer {
    thr_timer_t*       next;     /* next in free list */
    timer_t            id;       /* TIMER_ID_NONE iff free or dying */
    clockid_t          clock;
    pthread_t          thread;
    pthread_attr_t     attributes;
    thr_timer_func_t   callback;
    sigval_t           value;

    /* the following are used to communicate between
     * the timer thread and the timer_XXX() functions
     */
    pthread_mutex_t           mutex;     /* lock */
    pthread_cond_t            cond;      /* signal a state change to thread */
    int volatile              done;      /* set by timer_delete */
    int volatile              stopped;   /* set by _start_stop() */
    struct timespec volatile  expires;   /* next expiration time, or 0 */
    struct timespec volatile  period;    /* reload value, or 0 */
    int volatile              overruns;  /* current number of overruns */
};
1、指向当前的空闲队列的指针

2、定义相关的线程 信号量 以及对应的回调的函数

3、定义一些在时间片的线程与一些函数之间互相调用的变量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: