commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r7015 - in gnuradio/branches/developers/eb/gcell/src:


From: eb
Subject: [Commit-gnuradio] r7015 - in gnuradio/branches/developers/eb/gcell/src: include lib
Date: Wed, 21 Nov 2007 19:32:59 -0700 (MST)

Author: eb
Date: 2007-11-21 19:32:54 -0700 (Wed, 21 Nov 2007)
New Revision: 7015

Modified:
   gnuradio/branches/developers/eb/gcell/src/include/compiler.h
   gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc.h
   gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc_private.h
   gnuradio/branches/developers/eb/gcell/src/lib/gc_client_thread_info.h
   gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
   gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.h
Log:
create cache-aligned data structures

Modified: gnuradio/branches/developers/eb/gcell/src/include/compiler.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/include/compiler.h        
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/include/compiler.h        
2007-11-22 02:32:54 UTC (rev 7015)
@@ -26,6 +26,7 @@
  * \brief Compiler specific hackery.  These are for GCC.
  */
 
+#define _AL8   __attribute__((aligned (8)))
 #define _AL16  __attribute__((aligned (16)))
 #define _AL128 __attribute__((aligned (128)))
 

Modified: gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc.h     
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc.h     
2007-11-22 02:32:54 UTC (rev 7015)
@@ -101,10 +101,10 @@
   uint64_t      u64;
   float                 f;
   double        d;
-  //float complex       fc;    //  64-bits (C99)
-  //double complex dc;    // 128-bits (C99)
+  //float complex  fc; //  64-bits (C99)
+  //double complex dc;  // 128-bits (C99)
   gc_eaddr_t    ea;    //  64-bits
-} _AL16 gc_arg_union_t;
+} _AL8 gc_arg_union_t;
 
 
 /*!

Modified: 
gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc_private.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc_private.h     
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/include/gc_job_desc_private.h     
2007-11-22 02:32:54 UTC (rev 7015)
@@ -29,12 +29,12 @@
  */
 typedef struct gc_job_desc_private
 {
-  gc_eaddr_t   next;           // used to implement job queue and free list
+  volatile gc_eaddr_t  next;           // used to implement job queue and free 
list
+  uint16_t             job_id;
 
   // FIXME:
   // notifier_method
   // notifier_arg
-  // location (where we're running)
   
 } gc_job_desc_private_t;
 

Modified: gnuradio/branches/developers/eb/gcell/src/lib/gc_client_thread_info.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/gc_client_thread_info.h       
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_client_thread_info.h       
2007-11-22 02:32:54 UTC (rev 7015)
@@ -22,7 +22,7 @@
 #define INCLUDED_GC_CLIENT_THREAD_INFO_H
 
 #include <omnithread.h>
-#include <gc_atomic.h>
+#include <boost/utility.hpp>
 
 enum gc_ct_state_t {
   CT_RUNNING,
@@ -38,20 +38,22 @@
  * store a pointer to one of these for each thread
  * that comes our way.
  */
-class gc_client_thread_info {
+class gc_client_thread_info : boost::noncopyable {
 public:
   gc_client_thread_info() :
-    d_free(1), d_state(CT_RUNNING), d_cond(&d_mutex) { }
+    d_free(1), d_state(CT_RUNNING), d_cond(&d_mutex),
+    d_jobs_were_waiting_for(0){ }
 
   ~gc_client_thread_info() {
     d_free = 1;
+    d_jobs_were_waiting_for = 0;
   }
 
   volatile uint32_t    d_free;         // is this cti free? (1->free, 0->in 
use)
   gc_ct_state_t                d_state;
   omni_mutex           d_mutex;        // used to suspend/resume client
   omni_condition       d_cond;         // used to suspend/resume client
-  unsigned long                d_jobs_were_waiting_for[0];  // bitvector
+  unsigned long               *d_jobs_were_waiting_for;  // bitvector
 };
 
 #endif /* INCLUDED_GC_CLIENT_THREAD_INFO_H */

Modified: gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc        
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc        
2007-11-22 02:32:54 UTC (rev 7015)
@@ -26,15 +26,17 @@
 
 #include <stdio.h>
 #include <stdexcept>
+#include <stdlib.h>
 
 static const bool VERBOSE = true;
 
-static const unsigned int DEFAULT_MAX_JOBS = 256;
+static const size_t CACHE_LINE_SIZE = 128;
+static const unsigned int DEFAULT_MAX_JOBS = 128;
 static const unsigned int DEFAULT_MAX_CLIENT_THREADS = 64;
 
 
 // custom deleter of gang_contexts for use with boost::shared_ptr
-class gang_destroyer {
+class gang_deleter {
 public:
   void operator()(spe_gang_context_ptr_t ctx) {
     if (ctx){
@@ -46,9 +48,17 @@
   }
 };
 
+// custom deleter of anything that can be freed with "free"
+class free_deleter {
+public:
+  void operator()(void *p) {
+    free(p);
+  }
+};
 
+
 gc_job_manager_impl::gc_job_manager_impl(const gc_jm_options *options)
-  : d_nclients(0)
+  : d_nclients(0), d_client_thread(0), d_job_busy(0)
 {
   if (options != 0)
     d_options = *options;
@@ -102,7 +112,7 @@
   }
 
   if (d_options.gang_schedule){
-    d_gang = spe_gang_context_sptr(spe_gang_context_create(0), 
gang_destroyer());
+    d_gang = spe_gang_context_sptr(spe_gang_context_create(0), gang_deleter());
     if (!d_gang){
       perror("gc_job_manager_impl[spe_gang_context_create]");
       throw std::runtime_error("spe_gang_context_create");
@@ -125,13 +135,80 @@
     // FIXME load some code in the SPE
   }
 
-  // FIXME init d_jd
-  // FIXME init d_bvlen
-  // FIXME init d_job_busy
-  // FIXME init d_client_thread
 
+  // ----------------------------------------------------------------
+  // initalize the free list of job descriptors
   gc_jd_stack_init(&d_free_list);
 
+  printf("sizeof(d_jd[0]) = %d (0x%x)\n", sizeof(d_jd[0]), sizeof(d_jd[0]));
+  printf("max_jobs = %u\n", d_options.max_jobs);
+
+  // Initialize the array of job descriptors.
+  void *p = 0;
+  if (posix_memalign(&p, CACHE_LINE_SIZE,
+                    sizeof(d_jd[0]) * d_options.max_jobs) != 0){
+    perror("posix_memalign");
+    throw std::runtime_error("memory");
+  }
+  d_jd = (gc_job_desc_t *) p;
+  memset(d_jd, 0, sizeof(d_jd[0]) * d_options.max_jobs);
+
+  // This ensures that the memory associated with d_jd is
+  // automatically freed in the destructor or if an exception occurs
+  // here in the constructor.  It is admittedly a somewhat strange
+  // use; however we need the the custom deleter, which is only
+  // available with shared_ptr.
+  _d_jd_boost = boost::shared_ptr<void>((void *) d_jd, free_deleter());
+
+
+  // set unique job_id
+  for (int i = 0; i < (int) d_options.max_jobs; i++)
+    d_jd[i].sys.job_id = i;
+
+  // push them onto the free list
+  for (int i = d_options.max_jobs - 1; i >= 0; i--)
+    free_job_desc(&d_jd[i]);
+
+
+  // ----------------------------------------------------------------
+  // initialize d_client_thread
+
+  // FIXME robust deletion
+  d_client_thread = new gc_client_thread_info[d_options.max_client_threads];
+  
+  // ----------------------------------------------------------------
+  // initialize bitvectors
+
+  // initialize d_bvlen, the number of longs in job related bitvectors.
+  int bits_per_long = sizeof(unsigned long) * 8;
+  d_bvlen = (d_options.max_jobs + bits_per_long - 1) / bits_per_long;
+
+  // allocate all bitvectors in a single cache-aligned chunk
+  size_t nlongs = (1 + d_options.max_client_threads) * d_bvlen;
+  size_t byte_size = nlongs * sizeof(unsigned long);
+  p = 0;
+  if (posix_memalign(&p, CACHE_LINE_SIZE, byte_size) != 0){
+    perror("posix_memalign");
+    throw std::runtime_error("memory");
+  }
+  memset(p, 0, byte_size);
+
+  // let boost keep track of the storage
+  _d_all_bitvectors = boost::shared_ptr<void>(p, free_deleter());
+
+  // now point the other pointers into this storage.
+  // d_job_busy is the first one, followed by the ones in the client data
+
+  unsigned long *v = (unsigned long *) p;
+  d_job_busy = v;
+  v += d_bvlen;
+
+  for (unsigned int i = 0; i < d_options.max_client_threads; i++, v += d_bvlen)
+    d_client_thread[i].d_jobs_were_waiting_for = v;
+
+  // ----------------------------------------------------------------
+
+
   // FIXME sequence this...
   // FIXME create event handler thread
   // FIXME create N worker threads
@@ -145,6 +222,12 @@
   shutdown();
 
   // FIXME whatever else needs to be done
+
+  delete [] d_client_thread;
+  d_client_thread = 0;
+
+  d_jd = 0;            // handled via _d_jd_boost
+  d_job_busy = 0;      // handled via _d_all_bitvectors
 }
 
 bool

Modified: gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.h 
2007-11-21 23:39:04 UTC (rev 7014)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.h 
2007-11-22 02:32:54 UTC (rev 7015)
@@ -26,10 +26,12 @@
 #include "gc_client_thread_info.h"
 #include "gc_jd_stack.h"
 #include <libspe2.h>
+#include <vector>
 #include <boost/shared_ptr.hpp>
 
 typedef boost::shared_ptr<spe_gang_context> spe_gang_context_sptr;
 
+
 enum worker_state {
   WS_FREE,     // not in use
   WS_INIT,     // allocated and being initialized
@@ -58,14 +60,30 @@
   spe_gang_context_sptr  d_gang;               // boost::shared_ptr
   worker_ctx            d_worker[MAX_SPES];
 
-  gc_job_desc_t                *d_jd;                  // [limits.max_jobs]
+  // All of the job descriptors are hung off of here.
+  // We allocate them all in a single cache aligned chunk.
+  gc_job_desc_t                *d_jd;                  // [options.max_jobs]
+  boost::shared_ptr<void> _d_jd_boost;         // hack for automatic storage 
mgmt
 
-  int                   d_nclients;            // # of used entries in 
d_client_thread
-  gc_client_thread_info        *d_client_thread;       // 
[limits.max_client_threads]
+  int                   d_nclients;            // active length of 
d_client_thread
+  gc_client_thread_info *d_client_thread;      // [options.max_client_threads]
 
+  // We use bitvectors to represent the busy/free state of a job.  Each
+  // bitvector is d_bvlen longs in length.
   int                   d_bvlen;               // bit vector length in longs
-  unsigned long                *d_job_busy;            // bitvector of job's 
status 1=BUSY
 
+  // This contains the storage for all the bitvectors used by the job
+  // manager.  There's 1 for d_job_busy and 1 for each client thread
+  // [options.max_client_threads].  We allocate them all in a single
+  // cache aligned chunk.
+  boost::shared_ptr<void> _d_all_bitvectors;   // hack for automatic storage 
mgmt
+
+  // bitvector that describes that state of all jobs (1=BUSY).
+  // This points into _d_all_bitvectors.
+  unsigned long                *d_job_busy;
+
+  // The actually allocation chunk is hung off of d_jd.
+  // This is the lock free stack where we keep track of the free ones.
   gc_jd_stack_t                 d_free_list;           // stack of free job 
descriptors
 
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]