pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1) 详解

2023-05-16

发现很多文章都没有把pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1) 详细计算过程写出来,自己专门计算了一遍,附在文末。本例为man mmap中的原样实例程序,加上了一些额外的无关代码及打印输出信息 让总字节数超过一页大小sysconf(_SC_PAGE_SIZE)以方便查看调试信息

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
    char *addr;
    int fd;
    struct stat sb;
    off_t offset, pa_offset;
    size_t length;
    ssize_t s;

    if (argc < 3 || argc > 4) {
        fprintf(stderr, "%s file offset [length]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
        handle_error("open");

    if (fstat(fd, &sb) == -1)           /* To obtain file size */
        handle_error("fstat");

    offset = atoi(argv[2]);
    pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
        /* offset for mmap() must be page aligned */
     if (offset >= sb.st_size) {
        fprintf(stderr, "offset is past end of file\n");
        exit(EXIT_FAILURE);
    }

    if (argc == 4) {
        length = atoi(argv[3]);
        if (offset + length > sb.st_size)
            length = sb.st_size - offset;
                /* Can't display bytes past end of file */

    } else {    /* No length arg ==> display to end of file */
        length = sb.st_size - offset;
    }

    addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                MAP_PRIVATE, fd, pa_offset);
    if (addr == MAP_FAILED)
        handle_error("mmap");

    printf("length = %ld\n", length);
	printf("offset = %ld\n", offset);
	printf("pa_offset = %ld\n", pa_offset);
	printf("length + offset - pa_offset = %ld\n", length + offset - pa_offset);
    
    s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
    if (s != length) {
        if (s == -1)
            handle_error("write");

        fprintf(stderr, "partial write");
        exit(EXIT_FAILURE);
    }

    munmap(addr, length + offset - pa_offset);
    close(fd);

    exit(EXIT_SUCCESS);
}

//**额外增加的代码开始
//**加上了一些额外的无关代码及打印输出信息 让总字节数超过一页大小sysconf(_SC_PAGE_SIZE)以方便查看调试信息**开始
/* 
#include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    } 
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c
// #include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    }
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c#include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    } 
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c#include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    } 
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c#include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    } 
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c#include "head.h"
struct msgbuff{
    long mtype;
    char mtext[512];
};

void send_msg(int qid, int type, char *m_msg, int size){
    struct msgbuff msg;
    msg.mtype = type;
    strcpy(msg.mtext, m_msg);
    if(msgsnd(qid, (void *)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1){
        perror("msgsnd");
        exit(1);
    } 
}

void get_msg(int qid, int type){
    while (1){
        struct msgbuff msg;
        bzero(&msg, sizeof(msg));//清空缓冲区,也可用memmet实现
        if (msgrcv(qid, (void *)&msg, sizeof(msg.mtext),type, MSG_NOERROR) == -1) {
            perror("msgrcv");
            exit(1);
        }
        printf("抢到了资源: <%d> <%s>\n", type, msg.mtext);

    }
}

int main(int argc, char **argv){
    int opt, mode = 2, msgtype = 1;
    int msgq_id;
    char mtext[512] = {0};
    //mode == 1-> send
    while((opt = getopt(argc, argv, "st:rm:")) != -1){
        switch(opt){
            case 's':
                mode = 1;
                break;
            case 'r':
                mode = 2;
                break;
            case 't':
                msgtype = atoi(optarg);
                break;
            case 'm':
                strcpy(mtext, optarg);
                break;
            default:
                fprintf(stderr, "Usage: %s -[s|r] -t type -m msg\n", argv[0]);
                exit(1);
        }
    }
    //int msgget(key_t key, int msgflg);
    if((msgq_id = msgget(2021, IPC_CREAT | 0666)) < 0){
        perror("msgget");
        exit(1);
    }
    if (mode == 1){
        send_msg(msgq_id, msgtype, mtext, sizeof(mtext));
    } else {
        get_msg(msgq_id, msgtype);
    }

    return 0;
}
// ./a.out -s -t 1 -m "I'm the 1th!"
// ./a.out -r -t 1.msgq.c

*/
//**额外增加的结束
//加上了一些额外的无关代码及打印输出信息 让总字节数超过一页大小sysconf(_SC_PAGE_SIZE)以方便查看调试信息** 结束

编译命令:gcc mmap.c
程序执行格式: ./a.out file offset [length]
格式解析:./a.out +file 文件名 + offset偏移量 +length可选长度

./a.out mmap.c 10000

//执行结果,示例
length = 2266
offset = 10000
pa_offset = 8192

假设文件mmap.c文件大小为12266 ,
length =文件总大小(12266) - 偏移量offset(1000) = 2266

4096(sysconf(_SC_PAGE_SIZE)一页大小)

0001 0000 0000 0000 = 4096(sysconf(_SC_PAGE_SIZE)一页大小)
0000 1111 1111 1111 = (sysconf(_SC_PAGE_SIZE) - 1) =4095
~(0000 1111 1111 1111)
= 1111 0000 0000 0000 = ~ (sysconf(_SC_PAGE_SIZE) - 1) =61440

pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1)
=10000 & 61440
=(0010 0111 0001 0000) & (1111 0000 0000 0000)
=(0010 0000 0000 0000)
=8192 //pa_offset即内存中的页偏移量

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1) 详解 的相关文章

  • 计算R中目录的大小

    我想计算 R 中目录的大小 我尝试使用list info函数 不幸的是 它遵循符号链接 所以我的结果有偏差 return wrong size with duplicate counts for symlinks sum file info
  • Firebird BLR 是否包含相关字段大小?

    Firebird 和 InterBase 以 BLR 标记化 格式保存存储过程和触发器的编译形式 但我不太了解BLR的结构 字段大小是 BLR 的一部分吗 当存储过程包含两个字段 源和目标 并且稍后我将更改这两个字段的大小时 我会遇到一些问
  • JAVA中类的引用大小

    Java中类的引用大小是多少 对于特定的 JVM 和操作系统 它是否恒定 与引用的类无关 Class A Class B Class C A a B b C c 尺寸是a b and c无论大小都相同A B and C课程 是的 所有引用都
  • 更改 SweetAlert 上的图标图像大小

    我正在尝试更改 SweetAlert 上的图标图像大小 在 css 文件中我看到 sweet alert sa icon width 80px height 80px border 4px solid gray webkit border
  • 我只是“移动”图像,它的元数据就会改变......

    我只是复制了图像并将其保存到当前目录中的另一个临时文件夹中 没有任何修改 但图像占用了更多 磁盘空间 比它 字节大小 和 当我这样做时 我只丢失了大部分图像的元数据 例如位置数据 设备型号 F 号等Color space Alpha cha
  • 如何获取多字节字符串的字节大小

    如何在 Visual C 中获取多字节字符串的字节大小 有没有函数或者我必须自己计算字符 或者 更一般地说 如何获得 TCHAR 字符串的正确字节大小 解决方案 tcslen T TCHAR string sizeof TCHAR EDIT
  • 我可以在 jsplumb 中将偏移应用于连续锚点吗

    我想在 jsplumb 中使用 连续 锚点放置选项 这很好用 但是锚点一半放置在容器 div 内部 一半放置在容器外部 我希望锚点完全位于容器 div 之外 如果可能的话 div 和锚点之间的空间较小 一或两个像素 我的目的是将这些锚点放在
  • 状态栏高度始终返回0

    打电话时MediaQuery of context padding top在父小部件中 ProductsOverviewScreen 返回的值符合预期 24 但是当从嵌套小部件调用相同的属性时 ProductsGrid 我们正在谈论的父级的
  • C 中求短整型变量的最大值

    我正在做 K R 的练习 2 1 目标是计算不同变量类型的范围 下面是我计算最大值 a 的函数short int可以包含 short int max short void short int i 1 j 0 k 0 while i gt k
  • Flutter - 自动调整 AlertDialog 大小以适合列表内容

    我需要从休息网络服务动态加载列表城市 并让用户从警报对话框中选择一个城市 我的代码 createDialog fetchCities then response showDialog context context builder Buil
  • 如何让用户轻松选择在 Java Swing 应用程序中分配多少内存?

    我们有一个处理相对大量数据的 Swing 应用程序 例如 我们目前处理包含数百万行数据的 CSV 文件 出于性能和简单性的原因 我们将所有数据保留在内存中 然而 不同的用户需要处理的数据量以及 RAM 量也不同 创建安装程序时 我们当然需要
  • 如何在 C# 中获取文件夹大小? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在 C 中获取目录大小 目录中的文件 https stackoverflow com questions 1118568 how do i get a directory size files i
  • C# 中类实例的内存使用情况[重复]

    这个问题在这里已经有答案了 可能的重复 C NET 对象使用多少内存 https stackoverflow com questions 426396 how much memory does a c net object use 就像标题
  • C# Marshal.SizeOf

    我使用 Marshal SizeOf 来了解我的结构的大小 struct loginStruct public string userName public string password public loginStruct string
  • 使用 GhostScript 获取页面大小

    是否可以使用 GhostScript 获取页面大小 例如从 PDF 文档页面 我见过 bbox 设备 但它返回的是边界框 每页不同 而不是 PDF 页面的 TrimBox 或 CropBox 看http www prePressure co
  • UIScrollView setContentOffset:动画:不起作用

    我有两个无限的 UIScrollViews 的问题 它们没有正确改变它们的偏移量 第一个 UIScrollView 中的项目与第二个 UIScrollView 中的另一个项目相对应 然后 我想将单击的项目放在第二位 并为两个 UIScrol
  • Internet Explorer 10,最大 div 大小为 1.533.917 像素

    我需要制作一个非常大的 div 以百万像素为单位 搜索我发现这个线程证明 IE 可以管理最多 10 000 000 px 确定最大可能的 DIV 高度 https stackoverflow com questions 7719273 de
  • Java Toolkit 获取第二个屏幕尺寸

    我的计算机上插入了两个屏幕 想知道 JFrame 或 Toolkit 中是否有方法可以检测窗口位于哪个屏幕上 我有这个代码 java awt Toolkit getDefaultToolkit getScreenSize 它获取主屏幕的屏幕
  • bool 是否保证为 1 个字节?

    The Rust 文档 https doc rust lang org reference html primitive types是模糊的bool s size 它是否保证为 1 个字节 还是像 C 中那样未指定 fn main use
  • 如何查找页面上R图形的字节大小?

    我想监控 R 在各个页面上生成的图形的基本质量 例如每个页面的字节大小 我现在只能对平均页面进行质量保证 请参阅下面的章节 我认为这项任务必须有一些比一般措施更内置的东西 生成 4 页的代码Rplots pdf我想知道此处输出中每个页面的字

随机推荐