首页 > 代码库 > Android内核源码bionic目录下的源码的学习笔记

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

好记性不如烂笔头。今天要做的学习是关于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、定义一些在时间片的线程与一些函数之间互相调用的变量










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