1

スレッドにメモリ領域を提供し、メモリ管理の基本概念を適用する必要があります。アイデアは、スレッドローカルストレージを作成し、書き込み、読み取り、クローン、および消去で管理することです。問題は、TLS のスレッドに関連付けられているページを mprotect で保護解除しようとすると、エラーが発生することです。これは私の構造です:

各ページの割り当て

int cnt;
for (cnt = 0; cnt < page_num; cnt++) {
    struct page *p;
    p = (struct page *) calloc(1, sizeof(struct page));

    int *map =  mmap(0, page_size, 0, MAP_ANON | MAP_PRIVATE, 0, 0);
    if (map == MAP_FAILED) {
        perror("Error mmapping the file");
        exit(EXIT_FAILURE);
    }

    p->address = (unsigned int)map; 

mmap によってマップされますが、このコードでページを保護しようとすると (または保護を解除すると、同じエラーが発生し、初めて試みます)

for(int i = 0; i < currentTLS->page_num; i++){
    tls_unprotect(currentTLS->pages[i]);
}

そしてメソッド tls_unprotect:

void tls_protect(struct page *p){
  if (mprotect((void *) p->address,PAGESIZE, PROT_READ | PROT_WRITE)) {
      fprintf(stderr, "tls_unprotect: could not unprotect page\n");
      exit(errno);
  }
} 

保護方法は同じです。

エラー番号コードは 12 です。

どんな種類の助けにも感謝します。ありがとう。

4

1 に答える 1

3
p->address = (unsigned int)map; 

このキャストは非常に疑わしいです。ほとんどの 64 ビット システム (OS X AFAIK を含む) では、int幅が 32 ビットなので、ポインタを保持するには短すぎます。
そのキャストは、ポインターを構成する 8 バイトのうち 4 バイトを削除します。

p->addressとして宣言するvoid*必要があり、その代入はキャストをまったく必要としません。それを符号なし整数型として格納する必要がある場合は、uintptr_t(in <stdint.h>, C99) を使用します。

于 2012-05-29T05:39:10.447 に答える