Mona/アプリ質問所/共有メモリ の変更点



 [[Mona/アプリ質問所]]
 
 * 共有メモリ
 
 -やはりGUIは標準で日本語を使えないと意味がないと思ったのですが、日本語フォントをアプリごとに読み込むのは大変な無駄なので、とりあえずフォントデータの提供だけを行うGUIサーバを実装しようとしています。共有メモリを使うにはどうすれば良いでしょうか?このソースのここで使っているというポインタだけで結構ですのでよろしくお願いします。 -- [[Tino]] SIZE(10){2004-03-18 (木) 10:39:51}
 -共有メモリについては以下のような使い方になります。自分でサンプルを書いていたらちょっと使いづらいなあと感じたので何か要望がありましたら遠慮なくお申し付けください。また共有メモリはFATFSで使用されているはずなので参考になるかもしれません。 -- [[[[ひげぽん]]]] SIZE(10){2004-03-18 (木) 22:29:19}
  int MonaMain(List<char*>* pekoe)
  {
      /* 共有したい相手 */
      dword pid = Message::lookup("SHELL.SVR");
  
      /* メモリマップオブジェクト取得 */
      MemoryMap* mm = MemoryMap::create();
  
      /* 自分の0x90005000にpidの0x90000000を1Mバイトマッピングする */
      dword sharedid = mm->map(pid, 0x90000000, 0x90005000, 1 * 1024 * 1024);
  
      /* 共有エリアに書き込み */
      strcpy((char*)0x90005000, "data share top");
      strcpy((char*)0x90095000, "data share bottom");
  
      //    mm->unmap(sharedid);
  
      for (;;);
  }
  
  共有先での検証
  case(VK_9):
      printf("top    message is %s\n", (char*)0x90000000);
      printf("bottom message is %s\n", (char*)0x90090000);
 -ご回答ありがとうございます。サイズ<4096だとカーネルパニックになりますね。KB単位でページングしているからでしょうか? -- [[Tino]] SIZE(10){2004-03-25 (木) 00:05:55}
 - ご指摘の点、ご推測どおりです。4096byte以上かつ4096バイトの倍数にしてください。~
 注意書きを忘れていました。~
 ライブラリの方でチェック&4096バイトの倍数になるようにやった方が親切かも知れませんね。↓と同じく検討させていただきます -- ひげぽん
 --よろしくお願いします。 -- [[Tino]] SIZE(10){2004-03-25 (木) 00:49:17}
 -生アドレスを書かなくて済めば良いですね。以下適当なイメージコード。
  [サーバー]
  HANDLE global = GlobalAlloc(サイズ);
  byte* data = (byte*)GetGlobalAddress(global);
  dataに書き込み。
  メッセージ要求が来たらハンドルを返す。
  GlobalFree(global);
  ----
  [クライアント]
  HANDLE global = サーバーから取得したハンドル。
  mm->map(global); // globalは全プロセスで独立のIDなのでPID不要
  byte* data = (byte*)mm->getAddress(global);
  int size = mm->getSize(global);
  dataを処理。
  mm->unmap(global);
 -相手先のマップした領域(mm->map()の第2引数)はunmap()後も再利用できないんですね。そのため毎回ずらすような細工をしたらうまくいくみたいですが。 -- [[Tino]] SIZE(10){2004-03-26 (金) 02:39:56}
  // サーバー側
  int MonaMain(List<char*>* pekoe)
  {
      /* インスタンス取得 */
      MemoryMap* mm = MemoryMap::getInstance();
   
      /* 5000byteの共有メモリ(グローバル)を作成 実際のサイズは8192byteになる */
      dword id1 = mm->create(5000);
   
      if (id1 == 0)
      {
          printf("map create error = %x", mm->getLastError());
          exit(1);
      }
   
      printf("shared size = %d", mm->getSize(id1));
   
      /* 作成した共有メモリを自分の空間に貼り付ける */
      byte* p = mm->map(id1);
      if (p == NULL)
      {
          printf("map error\n");
          exit(1);
      }
   
      /* 共有エリアに書き込み */
      strcpy((char*)p, "data share top hello!!\n");
   
      /* ためしにServerにid1を送ってみよう */
      dword targetID = Message::lookupMainThread("KEYBDMNG.SVR");
      if (targetID == 0xFFFFFFFF)
      {
          printf("hello:Server not found\n");
          exit(1);
      }
   
      MessageInfo info;
      Message::create(&info, MSG_MEMORY_MAP_ID, id1, 0, 0, NULL);
   
      /* send */
      if (Message::send(targetID, &info)) {
          printf("hello send error\n");
      }
   
      /* 共有メモリを自分の空間からはずす */
      //mm->unmap(id1);
   
      return 0;
      for (;;);
  }
  // クライアント側
  case MSG_MEMORY_MAP_ID:
   
      {
          MemoryMap* mm = MemoryMap::getInstance();
          dword id = info.arg1;
          char* p = (char*)(mm->map(id));
          printf("[share!]%s\n", p);
          mm->unmap(id);
   
       }
 -アドバイスを受けましてMemory Mapの仕様を変えました。大変お手数ですがalpha6をダウンロード後、ご確認いただけると幸いです。 -- [[[[ひげぽん]]]] SIZE(10){2004-03-27 (土) 01:29:07}
 -大変遅くなりましたがα8にて試してみました。とても使いやすくなっていると思います。ありがとうございます。 -- [[Tino]] SIZE(10){2004-04-02 (金) 03:00:14}
 -ところで共有メモリのサイズを丸めるのにこんな式を使っていました。 -- [[Tino]] SIZE(10){2004-04-02 (金) 03:02:20}
  size = (size + 4095) >> 12 << 12;
 --この手の式を作るのにPythonは対話的で便利ですよ。でも私はPythonでプログラムを作ったことはなくて、こんな感じで電卓としてしか使っていませんが。 -- [[Tino]] SIZE(10){2004-04-02 (金) 03:02:20}
  $ python
  Python 2.3 (#1, Aug  5 2003, 09:49:11)
  [GCC 3.2 20020927 (prerelease)] on cygwin
  Type "help", "copyright", "credits" or "license" for more information.
  >>> a=0;(a+4095)>>12<<12
  0
  >>> a=1;(a+4095)>>12<<12 ← カーソルキーの[↑]で履歴を出して数字だけ修正
  4096
  >>> a=4096;(a+4095)>>12<<12
  4096
  >>> a=4097;(a+4095)>>12<<12
  8192
 --size=(size+4095)&0xFFFFF000; の方がいいかなと思いました。細かいですけど。 -- [[nikq]] SIZE(10){2004-04-02 (金) 11:54:04}
 --- nikqさんいただきました!
 --なるほど。 -- [[Tino]] SIZE(10){2004-04-02 (金) 12:02:12}
 -それはともかく、なぜかクライアント側ではmap()してもアドレスが0x90000000番台にならないようで、データがきちんと受け取れないようです。 -- [[Tino]] SIZE(10){2004-04-02 (金) 03:19:07}
 --ちょっとお手上げなのでコードとFDイメージだけ置いて寝ます……。 -- [[Tino]] SIZE(10){2004-04-02 (金) 03:19:41}
 --&ref(SharedMemory.zip);
 -ご迷惑おかけしております。原因調査中ですがMemory Mapクラスのコンストラクタが呼ばれずMemory Map::nextAddressが初期_されていないのが原因のようです。シングルトンの書き方がわるいのか。Monaのelfローダーがわるいのか・・・ -- [[[[ひげぽん]]]] SIZE(10){2004-04-02 (金) 12:34:15}
 -- %%対応しました(&ref(040402mona_v1.0.tar.gz);)今夜にでも緊急にα9をリリースします。%%リリースしました。~
 MemoryMap::getInstance()の戻り値が MemoryMap* -> MemoryMap&に変更になりました。~
 共有のコードについてはhello.cpp, KeyboardServer.cppでテストしていますので御参考になれば幸いです。御迷惑をおかけしました -- [[ひげぽん]]
 --ご対応ありがとうございます。シングルトンということですが、その場合メンバもすべてstaticにしてしまって、getInstance()自体を不要にしてしまった方が使い勝手が良いと思います。MonaGUIのApplicationクラスはそういう仕様にしています。(Windows Formsの真似ですが) -- [[Tino]] SIZE(10){2004-04-02 (金) 20:52:19}
 -なるほど。MemoryMapはmap/unmap時にメモリをnewする可能性があるのですが(今の実装ではサボっています)その場合も全メソッドをstaticにする感じでしょうか?流儀の問題化とは思いますが。基本を知らないものですいません。 -- [[[[ひげぽん]]]] SIZE(10){2004-04-02 (金) 21:29:05}
 --メモリをnewすることについての危惧が良く分からないです。本当にシングルトンであれば、メンバを全部staticにしても何の影響もないはずです。流儀については、インスタンスを参照で渡されると色々と使い勝手が悪いので(後で代入できないとかポインタが取れないとか)、メンバを全部staticにした方が使い勝手が良いという話です。 -- [[Tino]] SIZE(10){2004-04-02 (金) 21:34:26}
 --簡単に言うと、getInstance()で得られるインスタンスがシングルトンの場合、MemoryMap::getInstance().create(100);と書くのと、MemoryMap::create(100);と書くのとでは、後者の方が簡単という話です。後者の場合、create()内部でシングルトンのインスタンスを操作するとすれば(現実的には各種パラメータをstaticなメンバ変数として操作した方が実装が単純ですが)、実質的には何も変わらないわけです。初期化はMemoryMap::init();などと明示的に1回呼ばせるようにすれば簡単です。libuserのスタートアップコードに埋め込めば、アプリ開発者側から意識することはありません。MonaGUIではそうやってApplicationクラスを初期化しています(まだソースを出していないもので、ですが)。 -- [[Tino]] SIZE(10){2004-04-02 (金) 21:41:43}
 -なるほどありがとうございます。うーむ。MemoryMapの修正はMona GUIがリリースされて落ち着いてからの方がよいですかねぇ。 -- [[[[ひげぽん]]]] SIZE(10){2004-04-02 (金) 22:32:11}
 --実は修正があるかもしれないと思って様子を見ていました。 -- [[Tino]] SIZE(10){2004-04-02 (金) 23:03:49}
 --おっと。急いでやってみます。 -- [[[[ひげぽん]]]] SIZE(10){2004-04-02 (金) 23:14:09}
 --ありがとうございます。お手数をお掛けします。 -- [[Tino]] SIZE(10){2004-04-02 (金) 23:21:20}
 --でっちあげました。またバグってたらごめんなさい。→α10(リリースしすぎw) -- [[[[ひげぽん]]]] SIZE(10){2004-04-02 (金) 23:30:44}
 --ありがとうございます!!さっそくチェックしてみます。 -- [[Tino]] SIZE(10){2004-04-02 (金) 23:39:20}
 -浮気していたので遅くなりましたが(謎)、α10、確認させていただきました。 -- [[Tino]] SIZE(10){2004-04-03 (土) 06:26:50}
 --共有メモリに関しては完璧です。素晴らしいです。焚き付けておいてこんなことを言うのもあれですが、実に簡潔で使いやすいです。共有メモリがこんなに簡単に使えるOSは知りません!! -- [[Tino]] SIZE(10){2004-04-03 (土) 06:28:16}
 --急いでリリースしたためと思いますが、起動時のロゴがalpha9のままですね。 -- [[Tino]] SIZE(10){2004-04-03 (土) 06:29:00}
 --WABAが落ちるようになってしまったみたいです。 -- [[Tino]] SIZE(10){2004-04-03 (土) 06:29:19}
 -alpha10にロゴを直しました。(CVS最新版で), WABAが落ちる理由が分からない・・・ -- [[[[ひげぽん]]]] SIZE(10){2004-04-03 (土) 12:00:21}
 --alpha10にロゴを直しました。(CVS最新版で), WABAが落ちる理由が分からない・・・ -- [[[[ひげぽん]]]] SIZE(10){2004-04-03 (土) 12:00:21}
 
 #comment

リロード   新規 編集 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.005 sec.