2016-05-29 5 views
2

メモリ位置への読み取りが無期限に長くなる可能性はありますか(および任意のタイムアウト後に読み取りを完了できる別のスレッド)最後に無期限にファイルにマップされたメモリにアクセスすることができます

例えば、ソケットをブロックして、我々はreadシステムコールを使用する際に停止させるプロセスを取得することができますが:

fd = socket(AF_UNIX, SOCK_DGRAM, 0); 
read(fd, buffer, 256); 

通常、我々はmmapソケットことはできませんが、私は基本的に起こるために同じことをしたいと思います直接メモリにアクセスするとき:

int x = *(int *)map; 

を私は、メモリアクセスを行うための技術を知っていますそれにアクセスする前のページにメモリをmadviseを使用してのように、時間がかかるが、私は最後にこれを取得する方法を探しています無期限に。

私はファイル上でmmapを使用し、そのファイルを「ロック」していると考えましたが、そのための適切なインターフェイスが見つかりませんでした。 flockシステムコールはこのようには動作しません。

具体的には、私はFreeBSD for x86-64アーキテクチャに興味がありますが、Linuxや他のアーキテクチャなどの他のUnixライクなシステムに対する回答も高く評価されます。

+0

メモリアクセスをブロックする場合は、NFSマウントでファイルをmmap()し、このメモリ上で実際のランダムアクセスを実行できます。 – wildplasser

+0

ファイルがカスタム['FUSE'マウント](https://en.wikipedia.org/wiki/Filesystem_in_Userspace)にある場合は、任意の動作を取得できます。 –

答えて

3

mprotect(..., PROT_NONE)を使用して、mapを含むページにアクセスできないとマークすることができます。アクセスしようとすると、ページ違反が発生し、SIGSEGVが発生します。

siginfo_t引数で宣言されたSIGSEGVのハンドラをインストールできます。この構造体のsi_addrメンバを調べて、フォールトアドレスがmapと一致するかどうかを確認します。これにより、このアドレスへのアクセスを、コード内の実際のバグである他のフォルト(NULLデリファレンスなど)と区別することができます。そうであれば、信号ハンドラは他のスレッドが続行するようになるまで待つことができます。準備ができたらmprotectPROT_READ(あるいはPROT_WRITE)を呼び出し、シグナルハンドラから戻ります。障害のある命令が再開され、実行が継続されます。

これはかなり醜いハックです、なぜ私はあなたがこれを行う必要があると思うかについての良い見栄えをお勧めします。あなたの質問はXY problemのようです。

+0

私はあなたの提案を実装しました。これはユーザランドアクセス(EG: '*(int *)buffer = 0;')で動作しますが、私の究極の目標であったカーネルからの書き込みをフリーズしません((ucontext_t *)バッファ); ')。 – CHRIS

+0

@CHRIS:カーネルモードはまったく別の動物です。それがあなたの目標だったら、私はあなたがそう言ったと思う。そうであれば、おそらく新しい質問をするべきです。 –

+0

私は最初に説明した質問のためにあなたの答えを受け入れるでしょう。ありがとう。 – CHRIS

関連する問題