-1

多くのオペレーティング システムでは、マップ ファイルをメモリに保存し、遅延して読み取ることができます。オペレーティング システムがこれを行うことができれば、サンクから通常のポインタを作成する力が効果的に得られます。

アプリケーション プログラマが自分のサンクからポインタを作成できるオペレーティング システムはありますか?

パイプを作成し、それをメモリにマップし、プロセスをパイプに接続して、私が話していることのいくつかを達成できるため、限られた範囲でオペレーティングシステムがすでにこの機能をサポートしていることを知っているので、この機能はあまりないようです不可能または不合理。

この機能の簡単な例は、逆参照された回数をカウントするポインターです。次のプログラムは、0 を出力し、次に 1 を出力します。

static void setter(void* environment, void* input) {
 /* You can't set the counter */
}

static void getter(void* environment, void* output) {
  *((int*)output) = *((int*)environment)++;
}

int main(int argc, char** argv) {
 volatile int counter = 0;
 volatile int * const x = map_special_voodoo_magic(getter, setter, sizeof(*x),
                                                   &counter);

 printf("%i\n", *x);
 printf("%i\n", *x);

 unmap_special_voodoo_magic(x);
}

PS x が指す値が予期せず変更されるため、volatile 修飾子が必要です。同様に、x を逆参照するとカウンターが変更されるとコンパイラが考える理由がないので、そこにも volatile が必要ですか?

4

1 に答える 1

1

次のコードにはエラーチェックがなく、完全な実装ではありません。ただし、次のコードは、サンクをポインターにする方法の基本的な考え方を示しています。特に、値4はオンデマンドで計算され、以前はメモリに割り当てられていません。

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>

void * value;

static void catch_function(int signal, siginfo_t* siginfo,
                 void* context) {
    if (value != siginfo->si_addr) {
        puts("ERROR: Wrong address!");
        exit(1);
    }

    mmap(value, sizeof(int), PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED
                        | MAP_ANON, -1, 0);

    *((int*)value) = 2 * 2;
}

int main(void) {
    struct sigaction new_action;

    value = mmap(NULL, sizeof(int), PROT_NONE, MAP_ANON | MAP_SHARED, -1,
                    0);

    sigemptyset(&new_action.sa_mask);

    new_action.sa_sigaction = catch_function;
    new_action.sa_flags = SA_SIGINFO;

    sigaction(SIGBUS, &new_action, NULL);

    printf("The square of 2 is: %i\n", *((int*)value));

    munmap(value, sizeof(int)); 

    return 0;
}
于 2012-08-25T23:19:10.500 に答える