OSDN Git Service

2005-08-02 Dave Brolley <brolley@redhat.com>
authorbrolley <brolley>
Tue, 2 Aug 2005 18:53:10 +0000 (18:53 +0000)
committerbrolley <brolley>
Tue, 2 Aug 2005 18:53:10 +0000 (18:53 +0000)
        * sidbusutil.h (bus_arbitrator): Remove passthrough_pin.
        (check_passthrough): Now takes 'upstream' argument. Correct all calls.
        Don't check passthrough_pin here.
        (access_latency): New virtual method of bus_arbitrator.
        * sidblockingutil.h (blocking_component): Initialize still_blockable
        and control_status. Add blockable? using add_attribute_notify.
        (wait_for_child_thread): Assert that control_status != ctl_child_start.
        Return control_status.
        (child_completed): Set blockable to still_blockable.
        (set_blockable): New method of blocking_component.
        (still_blockable): New member of blocking_component.

sid/include/ChangeLog
sid/include/sidblockingutil.h
sid/include/sidbusutil.h

index 8cdc296..5c340ef 100644 (file)
@@ -1,3 +1,17 @@
+2005-08-02  Dave Brolley  <brolley@redhat.com>
+
+       * sidbusutil.h (bus_arbitrator): Remove passthrough_pin.
+       (check_passthrough): Now takes 'upstream' argument. Correct all calls.
+       Don't check passthrough_pin here.
+       (access_latency): New virtual method of bus_arbitrator.
+       * sidblockingutil.h (blocking_component): Initialize still_blockable
+       and control_status. Add blockable? using add_attribute_notify.
+       (wait_for_child_thread): Assert that control_status != ctl_child_start.
+       Return control_status.
+       (child_completed): Set blockable to still_blockable.
+       (set_blockable): New method of blocking_component.
+       (still_blockable): New member of blocking_component.
+
 2005-06-03  Jim Blandy  <jimb@redhat.com>
 
        * configure.in: Remove call to AC_ARG_PROGRAM, to avoid autoconf
index 838af63..79ecb62 100644 (file)
@@ -1,6 +1,6 @@
 // sidblockingutil.h - Elements used for blockable components.  -*- C++ -*-
 
-// Copyright (C) 2004 Red Hat.
+// Copyright (C) 2004, 2005 Red Hat.
 // This file is part of SID and is licensed under the GPL.
 // See the file COPYING.SID for conditions for redistribution.
 
@@ -28,17 +28,50 @@ namespace sidutil
       self (child_self),
       child_created (false),
       child_thread_function (f),
-      blockable (false)
+      blockable (false),
+      still_blockable (false),
+      control_status (ctl_parent)
       {
        add_attribute ("name", &name);
-       add_attribute ("blockable?", & blockable, "setting");
+       add_attribute_notify ("blockable?", & still_blockable, this,
+                             & blocking_component::set_blockable,
+                             "setting");
       }
     ~blocking_component () throw()
       {
       }
 
+    // -------------------------------------------------------------------
+    // Child thread management
+    //
+  public:
+    void child_init ()
+      {
+       log (10, "%s: child_init\n", name.c_str ());
+       assert (child_created);
+       // Lock both mutexes
+       pthread_mutex_lock (& child_resume_mutex);
+       pthread_mutex_lock (& child_stopped_mutex);
+      }
+
   protected:
-    // Called by the parent thread to ensure that a child thread exists
+    void parent_init ()
+      {
+       log (10, "%s: parent_init\n", name.c_str ());
+
+       // Create mutexes for synchronizing the parent and child threads
+       pthread_mutex_init (& child_resume_mutex, NULL);
+       pthread_cond_init (& child_resume_condition, NULL);
+       pthread_mutex_init (& child_stopped_mutex, NULL);
+       pthread_cond_init (& child_stopped_condition, NULL);
+
+       // Lock both mutexes
+       pthread_mutex_lock (& child_resume_mutex);
+       pthread_mutex_lock (& child_stopped_mutex);
+       control_status = ctl_parent;
+      }
+
+    // Called to ensure that a child thread exists
     //
     void need_child_thread ()
       {
@@ -81,33 +114,12 @@ namespace sidutil
        return wait_for_child_thread ();
       }
 
-  private:
-    // Called once by the parent thread just before the child thread is
-    // created.
-    void parent_init ()
-      {
-       log (10, "%s: parent_init\n", name.c_str ());
-
-       // Create mutexes for synchronizing the parent and child threads
-       pthread_mutex_init (& child_resume_mutex, NULL);
-       pthread_cond_init (& child_resume_condition, NULL);
-       pthread_mutex_init (& child_stopped_mutex, NULL);
-       pthread_cond_init (& child_stopped_condition, NULL);
-
-       // Lock both mutexes
-       pthread_mutex_lock (& child_resume_mutex);
-       pthread_mutex_lock (& child_stopped_mutex);
-       control_status = ctl_parent;
-      }
-
-    // Called by the parent to wait for the child thread to give up control
-    //
     int wait_for_child_thread ()
       {
        log (10, "%s: wait_for_child_thread\n", name.c_str ());
 
        // Signal the child to resume
-       assert (control_status == ctl_parent);
+       assert (control_status != ctl_child_start);
        control_status = ctl_child_start;
        pthread_cond_signal (& child_resume_condition);
 
@@ -121,24 +133,11 @@ namespace sidutil
        pthread_mutex_lock (& child_resume_mutex);
 
        // Check the value of control_status
-       int s = control_status;
-       assert (s != ctl_child_start);
-       control_status = ctl_parent;
-       return s;
+       assert (control_status != ctl_child_start);
+       return control_status;
       }
 
   public:
-    // Called by the child thread once when it is created.
-    //
-    void child_init ()
-      {
-       log (10, "%s: child_init\n", name.c_str ());
-       assert (child_created);
-       // Lock both mutexes
-       pthread_mutex_lock (& child_resume_mutex);
-       pthread_mutex_lock (& child_stopped_mutex);
-      }
-
     // Called by the child thread to signal normal completion of the child task
     //
     void child_completed ()
@@ -146,6 +145,7 @@ namespace sidutil
        log (10, "%s: child_completed\n", name.c_str ());
        log (11, "%s: child sending completion signal\n", name.c_str ());
        control_status = ctl_child_complete;
+       blockable = still_blockable;
        child_wait_for_resume ();
       }
            
@@ -159,7 +159,7 @@ namespace sidutil
        child_wait_for_resume ();
       }
 
-  private:
+  protected:       
     // Called by the child thread to wait for a signal from the parent thread
     // to resume
     void child_wait_for_resume ()
@@ -182,9 +182,18 @@ namespace sidutil
        assert (control_status == ctl_child_start);
       }
 
+    void set_blockable ()
+      {
+       // Never change the status of 'blockable' while the child thread is
+       // active.
+       if (control_status == ctl_parent || control_status == ctl_child_complete)
+         blockable = still_blockable;
+      }
+
   protected:
     string name;
     bool blockable;
+    bool still_blockable;
     void *self;
     bool child_created;
     pthread_t child_thread;
index f076c9a..456ecfc 100644 (file)
@@ -1,6 +1,6 @@
 // sidbusutil.h -*- C++ -*- Different types and sizes of buses.
 
-// Copyright (C) 1999, 2000, 2001, 2002, 2004 Red Hat.
+// Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005 Red Hat.
 // This file is part of SID and is licensed under the GPL.
 // See the file COPYING.SID for conditions for redistribution.
 
@@ -1213,8 +1213,6 @@ namespace sidutil
        running_pin.set_active_high ();
        add_pin ("active", & active_pin);
        active_pin.set_active_high ();
-       add_pin ("passthrough", & passthrough_pin);
-       passthrough_pin.set_active_high ();
       }
     ~bus_arbitrator () throw () { }
 
@@ -1289,7 +1287,7 @@ namespace sidutil
     sid::bus::status
     write(int upstream, sid::host_int_4 addr, DataType data)
       {
-       if (ulog_level >= 8 || ! check_passthrough ())
+       if (ulog_level >= 8 || ! check_passthrough (upstream))
          log (5, "%s: received write request from %s interface at 0x%x\n",
               name.c_str (), up2str(upstream), addr);
        return arbitrate_write (upstream, downstream_for_address (addr), addr, data);
@@ -1299,7 +1297,7 @@ namespace sidutil
     sid::bus::status
     read(int upstream, sid::host_int_4 addr, DataType& data)
       {
-       if (ulog_level >= 8 || ! check_passthrough ())
+       if (ulog_level >= 8 || ! check_passthrough (upstream))
          log (5, "%s: received read request from %s interface at 0x%x\n",
               name.c_str (), up2str(upstream), addr);
        return arbitrate_read (upstream, downstream_for_address (addr), addr, data);
@@ -1335,7 +1333,7 @@ namespace sidutil
                                     DataType& data)
       {
        // Check for direct passthrough
-       if (check_passthrough ())
+       if (check_passthrough (upstream))
          return downstream_bus (downstream)->read (addr, data);
 
        // Prioritize the request
@@ -1354,7 +1352,7 @@ namespace sidutil
                                      DataType data)
       {
        // Check for direct passthrough
-       if (check_passthrough ())
+       if (check_passthrough (upstream))
          return downstream_bus (downstream)->write(addr, data);
 
        // Prioritize the request
@@ -1410,22 +1408,22 @@ namespace sidutil
        return s;
       }
 
-    bool check_passthrough ()
+    virtual bool check_passthrough (int = 0)
       {
-       if (passthrough_pin.state () == binary_pin_active)
-         {
-           log (8, "%s: passthrough enabled\n", name.c_str ());
-           return true;
-         }
-
        if (running_pin.state () != binary_pin_active
            || active_pin.state () != binary_pin_active)
          {
            log (8, "%s: system is idle -- passthrough\n", name.c_str ());
            return true;
          }
-      return false;
-    }
+       return false;
+      }
+
+  protected:
+    // Methods for timing
+    //
+    // Default to no latency
+    virtual sid::host_int_2 access_latency (bus_request &r) { return 0; }
 
   protected:
     // Route locking
@@ -1457,7 +1455,6 @@ namespace sidutil
     //
     binary_input_pin running_pin;
     binary_input_pin active_pin;
-    binary_input_pin passthrough_pin;
   };
 }