打印
[其他ST产品]

ST源码分析-st_thread_create - 弦外之音

[复制链接]
楼主: 9dome猫
手机看帖
扫描二维码
随时随地手机跟帖
41
ousj| | 2023-4-21 21:33 | 只看该作者 回帖奖励 |倒序浏览
为什么 stk_size 要是 操作系统 内存页大小的 倍数

使用特权

评论回复
42
zwll| | 2023-4-21 21:35 | 只看该作者
这个涉及到内存对齐,虚拟内存跟物理内存的映射原理

使用特权

评论回复
43
zwll| | 2023-4-21 21:37 | 只看该作者
通俗来说,是为了让内存使用更加高效

使用特权

评论回复
44
langgq| | 2023-4-21 21:38 | 只看该作者
mmap 的用法谁能说下

使用特权

评论回复
45
zwll| | 2023-4-21 21:40 | 只看该作者
把文件映射到内存

使用特权

评论回复
46
pengf| | 2023-4-21 21:41 | 只看该作者
例如把 2G 的大文件映射到内存,然后写内存就相当于写文件,但是并不会占用 2G 的物理内存。

使用特权

评论回复
47
guoyt| | 2023-4-21 21:43 | 只看该作者
mmap 他这个映射是虚拟的,如果不使用文件映射,可以把 fd 设置为 -1 就是 匿名映射。

使用特权

评论回复
48
chenho| | 2023-4-21 21:45 | 只看该作者
alloc 函数申请的是实实在在的物理内存,物理内存的使用量会增加

使用特权

评论回复
49
bqyj| | 2023-4-21 21:48 | 只看该作者
calloc 会初始化为 0,会导致 commit

使用特权

评论回复
50
bqyj| | 2023-4-21 21:51 | 只看该作者
物理内存的使用是实实在在增加了 56 字节。

使用特权

评论回复
51
renyaq| | 2023-4-21 21:53 | 只看该作者
实际上 他还加了 2*REDZONE,多了两个内存页大小

使用特权

评论回复
52
bqyj| | 2023-4-21 21:55 | 只看该作者
为什么要冗余两个内存页大小

使用特权

评论回复
53
huwr| | 2023-4-21 21:57 | 只看该作者
bqyj 发表于 2023-4-21 21:55
为什么要冗余两个内存页大小

看文章《ST源码分析-内存保护》

使用特权

评论回复
54
9dome猫|  楼主 | 2023-4-21 23:18 | 只看该作者
下面继续 分析 _st_md_cxt_save 函数的代码:

_st_md_cxt_save:
        /*
         * Save registers.
         */
        movq %rbx, (JB_RBX*8)(%rdi)
        movq %rbp, (JB_RBP*8)(%rdi)
        movq %r12, (JB_R12*8)(%rdi)
        movq %r13, (JB_R13*8)(%rdi)
        movq %r14, (JB_R14*8)(%rdi)
        movq %r15, (JB_R15*8)(%rdi)

使用特权

评论回复
55
9dome猫|  楼主 | 2023-4-21 23:18 | 只看该作者
上面的代码从逻辑是看,就是保存 6 个寄存器 的值到 pthread->context (jmp_buf)里面。

他这个是直接搞清楚了 jmp_buf 的内存布局,然后按字段来填数据。没有直接用 C语言的函数 setjmp() 跟 longjmp() 来操作 jmp_buf,而是自己写汇编来操作 jmp_buf。

使用特权

评论回复
56
9dome猫|  楼主 | 2023-4-21 23:19 | 只看该作者
这里展示一下 jmp_buf 的定义:

/* Calling environment, plus possibly a saved signal mask.  */
struct __jmp_buf_tag
  {
    /* NOTE: The machine-dependent definitions of `__sigsetjmp'
       assume that a `jmp_buf' begins with a `__jmp_buf' and that
       `__mask_was_saved' follows it.  Do not move these members
       or add others before it.  */
    __jmp_buf __jmpbuf;     /* Calling environment.  */
    int __mask_was_saved;   /* Saved the signal mask?  */
    __sigset_t __saved_mask;    /* Saved signal mask.  */
  };


typedef struct __jmp_buf_tag jmp_buf[1];

使用特权

评论回复
57
9dome猫|  楼主 | 2023-4-21 23:19 | 只看该作者
上面的 jmp_buf[1] 实际上就是 定义一个数据,jmp_buf 就等于 __jmp_buf_tag[1] 。struct __jmp_buf_tag = {0} 跟 struct __jmp_buf_tag[1] = {0} 是不一样的,后面的是 __jmp_buf_tag* 是指针。

使用特权

评论回复
58
9dome猫|  楼主 | 2023-4-21 23:19 | 只看该作者
__jmp_buf 的定义如下,是一个 8 元素的数组:

typedef long int __jmp_buf[8];

使用特权

评论回复
59
9dome猫|  楼主 | 2023-4-21 23:19 | 只看该作者
接着看下面代码:

/* Save SP */
leaq 8(%rsp), %rdx
movq %rdx, (JB_RSP*8)(%rdi)
/* Save PC we are returning to */
movq (%rsp), %rax
movq %rax, (JB_PC*8)(%rdi)

使用特权

评论回复
60
9dome猫|  楼主 | 2023-4-21 23:19 | 只看该作者
这里用的是 lea 指令,lea 会把 8(%rsp) 这个内存地址 赋值给 rdx 寄存器 ,而不是把 内存地址的数据赋值给 rdx 寄存器,这个跟 mov 有差异

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则