Simple custom pager

Daniel Waddington d.waddington at ...60...
Sat Jul 9 01:45:14 CEST 2011


Hi,
As a toy exercise I'm trying to write a very simple custom pager which 
simply allocates memory from RAM to handle page faults.  When I try to 
handle the fault I get a region conflict exception.  Can someone tell me 
why??  I think I am missing something fundamental here.

Thanks
Daniel

----

#include <base/printf.h>
#include <base/sleep.h>
#include <base/rpc_server.h>
#include <cap_session/connection.h>
#include <dataspace/client.h>
#include <rom_session/connection.h>
#include <rm_session/connection.h>
#include <ram_session/connection.h>
#include <root/component.h>
#include <util/avl_string.h>
#include <util/misc_math.h>
#include <assert.h>

#define PAGE_SIZE 4096

using namespace Genode;

namespace Test
{

   /**
    * Example pager class
    *
    * @return
    */
   class Pager : public Thread<8192>
     {
   private:

     Signal_receiver _receiver;

   public:

     Signal_receiver *signal_receiver() { return &_receiver; }

     void entry();
     };

   /**
    * Example backing store class - this one uses physical memory
    *
    */
   class Physical_backing_store : public Signal_context
   {
   private:
     Rm_connection _rm;
     size_t _size;

   public:
     // ctor
     Physical_backing_store(size_t size): _rm(0,_size) {
       _size = size;
       assert(_size > 0);
     }

     virtual ~Physical_backing_store() {
     }

     /**
      * Page fault handler.
      *
      */
     void handle_fault()
     {
       Rm_session::State state = _rm.state();

       printf("Test::Physical_backing_store:: rm session state is %s, 
pf_addr=0x%lx\n",
              state.type == Rm_session::READ_FAULT  ? "READ_FAULT"  :
              state.type == Rm_session::WRITE_FAULT ? "WRITE_FAULT" :
              state.type == Rm_session::EXEC_FAULT  ? "EXEC_FAULT"  : 
"READY",
              state.addr);

       if (state.type == Rm_session::READY)
         return;

       try {

         Dataspace_capability _ds;
         try {
           _ds = env()->ram_session()->alloc(PAGE_SIZE);
         }
         catch(...) { PERR("Actual page allocation failed.\n"); }

         _rm.attach_at(_ds, state.addr & ~(PAGE_SIZE - 1));

         PDBG("attached data space OK!\n");
       }
       catch (Genode::Rm_session::Region_conflict) {
         PERR("Region conflict - this should not happen\n");
       }
       catch (Genode::Rm_session::Out_of_metadata) {
         PERR("Out of meta data!\n");
       }
       catch(...) {
         PERR("Something else caused attach to fail in fault handler.\n");
       }

       return;
     }

     Rm_connection *rm() { return &_rm; }
     Dataspace_capability ds() { return _rm.dataspace(); }

         void connect_pager(Pager& _pager) {
       /* connect pager signal receiver to the fault handler */
       _rm.fault_handler(_pager.signal_receiver()->manage(this));
     }

   };


   /**
    * Entry point for pager thread.
    *
    */
   void Pager::entry()
   {
     printf("Pager thread started OK.\n");

     while (true) {
       try {
         Signal signal = _receiver.wait_for_signal();

         for (int i = 0; i < signal.num(); i++) {
           static_cast<Physical_backing_store 
*>(signal.context())->handle_fault();
         }
       } catch (...) {
         PDBG("unexpected error while waiting for signal");
       }
     }
   }


}

int main()
{
   Genode::printf("Test-pager example. ;-))\n");

   Test::Pager _pager;

   /* start pager thread */
   _pager.start();

   /* create dataspace etc. */
   try {

     enum { MANAGED_DS_SIZE = 64*1024*1024 };
     Test::Physical_backing_store bs(MANAGED_DS_SIZE);

     /* connect pager to fault handler */
     bs.connect_pager(_pager);

     /* attach to dataspace */
     char * addr = (char*) env()->rm_session()->attach(bs.ds());
     assert(addr);

     /* trigger read fault */
     printf("!!!Triggering fault...\n");
     printf("%c%c%c\n",addr[0],addr[1],addr[2]);

     printf("Fault handled OK.\n");

   }
   catch(...) {
     PERR("Something failed ????.\n");
   }

   printf("test-pager completed.\n");
   Genode::sleep_forever();
   return 0;
}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.genode.org/pipermail/users/attachments/20110708/7ea8b2cf/attachment.html>


More information about the users mailing list