]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
*** empty log message ***
authorsage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 7 May 2005 01:50:44 +0000 (01:50 +0000)
committersage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 7 May 2005 01:50:44 +0000 (01:50 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@214 29311d96-e01e-0410-9327-a35deaab8ce9

14 files changed:
ceph/Makefile
ceph/common/Timer.cc
ceph/common/Timer.h
ceph/config.cc
ceph/include/Context.h
ceph/mds/CDir.h
ceph/mds/MDCache.cc
ceph/msg/CheesySerializer.h
ceph/msg/FakeMessenger.cc
ceph/msg/FakeMessenger.h
ceph/msg/MPIMessenger.cc
ceph/msg/MPIMessenger.h
ceph/msg/Messenger.h
ceph/test/mpitest.cc

index 6dc62b663b58ec636c37c97d7d7a6af9a684283b..39ce89c49c827bfdeca1ccb3ac76d53158cbc070 100644 (file)
@@ -30,10 +30,11 @@ COMMON_OBJS= \
        msg/error.o\
        common/Logger.o\
        common/clock.o\
+       common/Timer.o\
        config.o
 
-TEST_TARGETS = fakemds mpitest fakefuse
-TARGETS = import singleclient mpifuse
+TEST_TARGETS = fakemds mpitest
+TARGETS = import singleclient mpifuse fakefuse
 
 SRCS=*.cc */*.cc
 
index c691e9dd0c675f66a44e9294a6590100c5b73a6a..b3dcd38306e6650c38219fb72e424fcdfcb9b9a6 100644 (file)
 #include "Timer.h"
 
 #include "include/config.h"
+#include "include/Context.h"
+
+#include "msg/Messenger.h"
 
 #undef dout
 #define dout(x)  if (x <= g_conf.debug) cout << "Timer: "
 
 
+#include <signal.h>
+#include <sys/time.h>
+
+Messenger *messenger_to_kick = 0;
+Timer     *static_timer = 0;
+
+void timer_signal_handler(int sig)
+{
+  // kick messenger.
+  if (messenger_to_kick && static_timer) {
+       messenger_to_kick->trigger_timer(static_timer);
+  }
+}
+
+
+void Timer::register_timer()
+{
+  dout(10) << "register_timer installing signal handler" << endl;
+
+  /* only one of these per process.  
+        should be okay, i think.. in the cases where we have multiple people in the same
+        process (FakeMessenger), we're actually kicking the same event loop anyway.
+  */
+  // FIXME i shouldn't have to do this every time?
+  static_timer = this;
+  messenger_to_kick = messenger;
+  
+  // install handler
+  struct sigaction ac;
+  memset(&ac, sizeof(ac), 0);
+  ac.sa_handler = timer_signal_handler;
+  ///FIXMEac.sa_mask = 0;  // hmm.
+  
+  sigaction(SIGALRM, &ac, NULL);
+
+  // set alarm
+  double now = g_clock.gettime();
+  double delay = next_event_time() - now;
+  double sec;
+  double usec = modf(delay, &sec);
+
+  dout(10) << "setting itimer to go off in " << sec << "s " << usec << "us" << endl;
+  struct itimerval it;
+  it.it_value.tv_sec = (int)sec;
+  it.it_value.tv_usec = (int)(usec * 1000000);
+  it.it_interval.tv_sec = 0;   // don't repeat!
+  it.it_interval.tv_usec = 0;
+  setitimer(ITIMER_REAL, &it, 0);
+}
+
+void Timer::cancel_timer()
+{
+  // clear my callback pointers
+  messenger_to_kick = 0;
+  static_timer = 0;
+  
+  // remove my handler.  MESSILY FIXME
+  sigaction(SIGALRM, 0, 0);
+}
+
 
 void Timer::execute_pending()
 {
-  double now = clock.gettime();
+  double now = g_clock.gettime();
   dout(12) << "now = " << now << endl;
   
   while (event_map.size()) {
        Context *event = 0;
        
+       double next = next_event_time();
+       if (next > now) break;
+       
        { // scope this so my iterator is destroyed quickly
-         // check first event
-         map<double,Context*>::iterator it = event_map.begin();
-         if (it->first > now) {
-               dout(12) << "next event at " << it->first << ", stopping" << endl;
-               break;  // no events!
-         }
+         // grab first
+         set<Context*>::iterator it = event_map[next].begin();
          
-         // claim and remove from map
-         event = it->second;
-         event_map.erase(it);
-         
-         dout(5) << "executing event " << event << " scheduled for " << it->first << endl;
+         event = *it;
+         assert(event);
        }
+
+       // claim and remove from map
+       event_map[next].erase(event);
+       event_times.erase(event);
        
        // exec
-       assert(event);
+       dout(5) << "executing event " << event << " scheduled for " << next << endl;
+       
        event->finish(0);
        delete event;
   }
index 3915bfebba9fb51f3c3d2026d91c546ba17c4b30..5fd647ca3ef8dfb51e3f723389d9cbceb2adb38d 100644 (file)
@@ -1,26 +1,69 @@
 #ifndef __TIMER_H
 #define __TIMER_H
 
+#include "include/Context.h"
+#include "Clock.h"
+
+#include <map>
+#include <set>
+using namespace std;
+
+
 /*** Timer
  * schedule callbacks
  */
 
-class Timer {
+class Messenger;
 
-  // event map: time -> context
-  map<double, Context*> event_map;
+class Timer {
+ private:
+  map<double, set<Context*> > event_map;    // time -> (context ...)
+  map<Context*, double>        event_times;  // event -> time
+
+  // get time of the next event
+  double next_event_time() {
+       map< double, set<Context*> >::iterator it = event_map.begin();
+       return it->first;
+  }
+  
+  Messenger *messenger;
+  void register_timer();  // make sure i get a callback
+  void cancel_timer();  // make sure i get a callback
 
  public:
-  
+  Timer(Messenger *msg) { messenger = msg; }
+  ~Timer() { 
+       // cancel any wakeup crap
+       cancel_timer();
+
+       // 
+  }
+
   // schedule events
   void add_event_after(double seconds,
                                           Context *callback) {
-       add_event_at(clock.gettime(), callback);
+       add_event_at(g_clock.gettime() + seconds, callback);
   }
   
   void add_event_at(double when,
                                        Context *callback) {
+       // insert
+       event_map[when].insert(callback);
+       event_times[callback] = when;
+
+       // make sure i wake up (soon enough)
+       register_timer();
+  }
+
+  bool cancel_event(Context *callback) {
+       if (!event_times.count(callback)) 
+         return false;     // wasn't scheduled.
        
+       double when = event_times[callback];
+       event_times.erase(callback);
+       event_map[when].erase(callback);
+       if (event_map[when].empty()) event_map.erase(when);
+       return true;
   }
 
   // execute pending events
index 6df77120d45acb34e3a8a47a5984577aca7e5317..064a2d3364abd49689fa96aef783b4833409e675 100644 (file)
@@ -50,7 +50,7 @@ md_config_t g_conf = {
 
   // --- fakeclient (mds regression testing) ---
   num_fakeclient: 1000,
-  fakeclient_requests: 10,
+  fakeclient_requests: 100,
   fakeclient_deterministic: false,
 
   fakeclient_op_statfs:     false,
@@ -64,7 +64,7 @@ md_config_t g_conf = {
   fakeclient_op_readdir:  10,
   fakeclient_op_mknod:    100,
   fakeclient_op_link:       false,
-  fakeclient_op_unlink:   10,
+  fakeclient_op_unlink:   100,
   fakeclient_op_rename:   100,
 
   fakeclient_op_mkdir:    100,
index e669e7676c5264798281401d387eda86be47b33d..ca59d1601d51f1975ab376cd8459e9936d875f68 100644 (file)
@@ -2,10 +2,12 @@
 #ifndef __CONTEXT_H
 #define __CONTEXT_H
 
-#include <list>
-#include <assert.h>
 #include "config.h"
+
+#include <assert.h>
+#include <list>
 #include <iostream>
+using namespace std;
 
 class MDS;
 
index 1cad2a338abe82622781190f5edb09a742889c46..f54c3df3bbc10000490e3492b4f77d360b60c573 100644 (file)
@@ -157,6 +157,7 @@ static char* cdir_pin_names[CDIR_NUM_PINS] = {
 #define CDIR_WAIT_DNREAD        (1<<20)
 #define CDIR_WAIT_DNLOCK        (1<<21)
 #define CDIR_WAIT_DNUNPINNED    (1<<22)
+#define CDIR_WAIT_DNPINNABLE    (CDIR_WAIT_DNREAD|CDIR_WAIT_DNUNPINNED)
 
 #define CDIR_WAIT_DNREQXLOCK    (1<<23)
 
index 14581914ca4f059167d5cc6b7abf1422dace727d..1732b9cb8de0f14cc60c107f5b3a62ff9c788f97 100644 (file)
@@ -1098,7 +1098,7 @@ bool MDCache::path_pin(vector<CDentry*>& trace,
          // wait
          if (c) {
                dout(10) << "path_pin can't pin " << *dn << ", waiting" << endl;
-               dn->dir->add_waiter(CDIR_WAIT_DNREAD,
+               dn->dir->add_waiter(CDIR_WAIT_DNPINNABLE,   
                                                        dn->name,
                                                        c);
          } else {
index 883710f06ca402adebd1f7149ed103b44eab7669..78ed9377cb153bdef099c5410e14bd0b66407f9d 100644 (file)
@@ -9,6 +9,8 @@
 #include "Cond.h"
 #include "Mutex.h"
 
+#include <assert.h>
+
 #include <map>
 using namespace std;
 
@@ -38,6 +40,10 @@ class CheesySerializer : public Messenger,
                                        int port=0, int fromport=0);     // doesn't block
   Message *sendrecv(Message *m, msg_addr_t dest, 
                                        int port=0);                     // blocks for matching reply
+
+  void trigger_timer(class Timer *t) {
+       assert(0);
+  }
 };
 
 #endif
index 6c418caa42d6298287e15a98e6b2d563948f09ac..84a9982b897bb9811d77bdbb698082853258e2c0 100644 (file)
@@ -5,6 +5,7 @@
 #include "FakeMessenger.h"
 #include "mds/MDS.h"
 
+#include "common/Timer.h"
 #include "common/LogType.h"
 #include "common/Logger.h"
 
@@ -78,7 +79,7 @@ void fakemessenger_stopthread() {
 }
 
 
-
+Timer *pending_timer = 0;
 
 // lame main looper
 
@@ -100,6 +101,16 @@ int fakemessenger_do_loop_2()
        
        dout(11) << "do_loop top" << endl;
 
+       // timer?
+       if (pending_timer) {
+         Timer *t = pending_timer;
+         pending_timer = 0;
+
+         dout(5) << "pending timer" << endl;
+         t->execute_pending();
+       }
+
+       // messages
        map<int, FakeMessenger*>::iterator it = directory.begin();
        while (it != directory.end()) {
          Message *m = it->second->get_message();
@@ -155,6 +166,8 @@ FakeMessenger::FakeMessenger(long me)
   whoami = me;
   directory[ whoami ] = this;
 
+  pending_timer = 0;
+
   cout << "fakemessenger " << whoami << " messenger is " << this << endl;
 
   string name;
@@ -183,6 +196,15 @@ int FakeMessenger::shutdown()
   directory.erase(whoami);
 }
 
+void FakeMessenger::trigger_timer(Timer *t) 
+{
+  // note timer to call
+  pending_timer = t;
+
+  // wake up thread?
+  cond.Signal();  // why not
+}
+
 
 int FakeMessenger::send_message(Message *m, msg_addr_t dest, int port, int fromport)
 {
index 4241eb6be1b443f78644401b534070fd19e85fc0..0b0e7f92b6a51664f9ed4b8152edd8bd21cfb754 100644 (file)
@@ -8,6 +8,8 @@
 #include <list>
 #include <map>
 
+class Timer;
+
 class FakeMessenger : public Messenger {
  protected:
   int whoami;
@@ -25,6 +27,9 @@ class FakeMessenger : public Messenger {
   
   // use CheesySerializer for now!
   virtual Message* sendrecv(Message *m, msg_addr_t dest, int port=0) { assert(0); };
+
+  // events
+  virtual void trigger_timer(Timer *t);
 };
 
 int fakemessenger_do_loop();
index f0fe2f560287d054dcebc87c04d4ce5b0d56c778..a4ea542cb4ad9011c6055c6bbdc0684c251aa885 100644 (file)
@@ -2,6 +2,8 @@
 #include "include/config.h"
 #include "include/error.h"
 
+#include "common/Timer.h"
+
 #include "MPIMessenger.h"
 #include "Message.h"
 
@@ -317,6 +319,14 @@ int MPIMessenger::shutdown()
 
 
 
+/*** events
+ */
+
+void MPIMessenger::trigger_timer(Timer *t)
+{
+  assert(0); //implement me
+}
+
 /***
  * public messaging interface
  */
index b20bc4de139f560c8ed0c4962a1963f665a84dc9..c56e25d541c629b7b11c1a33b5cdecbfa0d4d0e8 100644 (file)
@@ -10,6 +10,7 @@
                                                                                 (dest) : \
                                                                                 ((NUMMDS+NUMOSD)+(((dest)-NUMMDS-NUMOSD) % ((world)-NUMMDS-NUMOSD))))
 
+class Timer;
 
 class MPIMessenger : public Messenger {
  protected:
@@ -26,6 +27,9 @@ class MPIMessenger : public Messenger {
   // message interface
   virtual int send_message(Message *m, msg_addr_t dest, int port=0, int fromport=0);
   virtual Message* sendrecv(Message *m, msg_addr_t dest, int port=0);
+
+  // events
+  virtual void trigger_timer(Timer *t);
 };
 
 /**
index 6ebefdfda4ce585dd27f728f4d396632d174452a..2d7ce1b2cc387d953c9202071bf7d027b48799bd 100644 (file)
@@ -9,6 +9,7 @@ using namespace std;
 #include "Dispatcher.h"
 
 class MDS;
+class Timer;
 
 class Messenger {
  protected:
@@ -37,6 +38,8 @@ class Messenger {
   //virtual Message *recv() = 0
 
   
+  // events
+  virtual void trigger_timer(Timer *t) = 0;
 
 
   // -- incoming queue --
index d88396ee8586a2efd38b037d7b6636b50d13c482..8cb808ff6da65d688ada0241cc3f1ce287f6ef07 100644 (file)
@@ -58,7 +58,7 @@ int main(int argc, char **argv) {
   FakeClient *client[NUMCLIENT];
   for (int i=0; i<NUMCLIENT; i++) {
        if (myrank != MPI_DEST_TO_RANK(MSG_ADDR_CLIENT(i),world)) continue;
-       client[i] = new FakeClient(mdc, i, new MPIMessenger(MSG_ADDR_CLIENT(i)), g_conf.client_requests);
+       client[i] = new FakeClient(mdc, i, new MPIMessenger(MSG_ADDR_CLIENT(i)), g_conf.fakeclient_requests);
        client[i]->init();
   }