commit-gnuradio
[Top][All Lists]
Advanced

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

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


From: eb
Subject: [Commit-gnuradio] r7665 - in gnuradio/branches/developers/eb/gcell/src: lib lib/spu spu-include
Date: Wed, 13 Feb 2008 16:05:10 -0700 (MST)

Author: eb
Date: 2008-02-13 16:05:09 -0700 (Wed, 13 Feb 2008)
New Revision: 7665

Added:
   gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
Removed:
   gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c
Modified:
   gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
   gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
   gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
   gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
Log:
now using Lock-Line Reservation Lost event

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        
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc        
2008-02-13 23:05:09 UTC (rev 7665)
@@ -216,7 +216,7 @@
   // get a handle to the spe program
 
   // FIXME pass this in (or something)
-  const char *spu_progname = "../lib/spu/test_spu";
+  const char *spu_progname = "../lib/spu/gcell_spu_main";
 
   spe_program_handle_t *spe_image = spe_image_open(spu_progname);
   if (spe_image == 0){

Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am       
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am       
2008-02-13 23:05:09 UTC (rev 7665)
@@ -54,4 +54,4 @@
 LDADD = libgcell_spu.a
 
 noinst_PROGRAMS = \
-       test_spu
+       gcell_spu_main

Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c 
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c 
2008-02-13 23:05:09 UTC (rev 7665)
@@ -81,3 +81,16 @@
   return true;
 }
 
+
+void
+gc_jd_queue_getllar(gc_eaddr_t q)
+{
+  // get reservation that includes the tail of the queue
+  gc_eaddr_t   tail = q + offsetof(gc_jd_queue_t, tail);
+    
+  char _tmp[256];
+  char *buf = (char *) ALIGN(_tmp, 128);       // get cache-aligned buffer
+
+  mfc_getllar(buf, ALIGN128_EA(tail), 0, 0);
+  spu_readch(MFC_RdAtomicStat);
+}

Copied: gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c 
(from rev 7662, gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c)
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c          
                (rev 0)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c  
2008-02-13 23:05:09 UTC (rev 7665)
@@ -0,0 +1,283 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <sync_utils.h>
+#include "gc_spu_args.h"
+#include "gc_job_desc.h"
+#include "gc_mbox.h"
+#include "sys_tags.h"
+#include "gc_jd_queue.h"
+#include "gc_methods.h"
+#include "gc_delay.h"
+
+static gc_spu_args_t   spu_args;
+
+// our working copy of the completion info
+static gc_comp_info_t  comp_info = {  
+  .in_use = 1,
+  .ncomplete = 0
+};
+
+static int ci_idx = 0;         // index of current comp_info
+static int ci_tags;            // two consecutive dma tags
+
+// ------------------------------------------------------------------------
+
+/*
+ * Wait until EA copy of comp_info[idx].in_use is 0
+ */
+static void
+wait_for_ppe_to_be_done_with_comp_info(int idx)
+{
+  char _tmp[256];
+  char *buf = (char *) ALIGN(_tmp, 128);       // get cache-aligned buffer
+  gc_comp_info_t *p = (gc_comp_info_t *) buf;
+
+  do {
+    mfc_getllar(buf, spu_args.comp_info[idx], 0, 0);
+    spu_readch(MFC_RdAtomicStat);
+    if (p->in_use == 0)
+      return;
+
+    gc_udelay(5);    // FIXME use the "lock-line reservation lost" event
+
+  } while (1);
+}
+
+static void
+flush_completion_info(void)
+{
+  if (comp_info.ncomplete == 0)
+    return;
+  
+  if (0){
+    static int total_jobs = 0;
+    static int total_msgs = 0;
+    total_msgs++;
+    total_jobs += comp_info.ncomplete;
+    printf("spe[%2d]: tj = %6d  tm = %6d\n", spu_args.spu_idx,
+          total_jobs, total_msgs);
+  }
+
+  // ensure that PPE is done with the buffer we're about to overwrite
+  wait_for_ppe_to_be_done_with_comp_info(ci_idx);
+
+  // dma the comp_info out to PPE
+  int tag = ci_tags + ci_idx;
+  mfc_putf(&comp_info, spu_args.comp_info[ci_idx], sizeof(gc_comp_info_t), 
tag, 0, 0);
+  mfc_write_tag_mask(1 << tag);                // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  // send it a message
+  spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_JOBS_DONE, ci_idx));
+
+  ci_idx ^= 0x1;       // switch buffers
+  comp_info.in_use = 1;
+  comp_info.ncomplete = 0;
+}
+
+// ------------------------------------------------------------------------
+
+static unsigned int backoff;           // current backoff value in clock cycles
+static unsigned int _backoff_start;
+static unsigned int _backoff_cap;
+
+/*
+ * For 3.2 GHz SPE
+ *
+ * 12    4095 cycles    1.3 us
+ * 13    8191 cycles    2.6 us
+ * 14   16383 cycles    5.1 us
+ * 15   32767 cycles   10.2 us
+ * 16                  20.4 us
+ * 17                  40.8 us
+ * 18                  81.9 us
+ * 19                 163.8 us
+ * 20                 327.7 us
+ * 21                 655.4 us
+ */
+static unsigned char log2_backoff_start[16] = {
+  12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16
+};
+  
+static unsigned char log2_backoff_cap[16] = {
+  17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21
+};
+  
+void
+backoff_init(void)
+{
+  _backoff_cap   = (1 << (log2_backoff_cap[(spu_args.nspus - 1) & 0xf])) - 1;
+  _backoff_start = (1 << (log2_backoff_start[(spu_args.nspus - 1) & 0xf])) - 1;
+  
+  backoff = _backoff_start;
+}
+
+void 
+backoff_reset(void)
+{
+  backoff = _backoff_start;
+}
+
+void
+backoff_delay(void)
+{
+  gc_cdelay(backoff);
+
+  // capped exponential backoff
+  backoff = ((backoff << 1) + 1) & _backoff_cap;
+}
+
+// ------------------------------------------------------------------------
+
+void
+process_job(gc_eaddr_t jd_ea, gc_job_desc_t *jd)
+{
+  // FIXME do something useful ;)
+
+  if (0){
+    static int total_jobs = 0;
+    total_jobs++;
+    printf("spe[%2d]: tij =%6d\n", spu_args.spu_idx, total_jobs);
+  }
+
+  if (0)
+    printf("spu[%d]: job_id = %3d  client_id = %3d\n",
+          spu_args.spu_idx, jd->sys.job_id, jd->sys.client_id);
+
+  jd->status = JS_OK;  // assume success
+
+  switch(jd->method){  // FIXME lookup method
+
+  case GCM_NOP:
+    break;
+
+  case GCM_UDELAY:
+    gc_udelay(jd->input.dir_val[0].u32);
+    break;
+
+  default:
+    jd->status = JS_UNKNOWN_METHOD;
+    break;
+  }
+
+  // FIXME copy indirect args in
+  // FIXME invoke method
+  // FIXME copy indirect args out
+  // FIXME copy jd back out
+
+  
+  // Tell PPE we're done with the job.
+  //
+  // We queue these up until we run out of room, or until we can send
+  // the info to the PPE w/o blocking.  The blocking check is in
+  // main_loop
+
+  comp_info.job_id[comp_info.ncomplete++] = jd->sys.job_id;
+
+  if (comp_info.ncomplete == GC_CI_NJOBS)
+    flush_completion_info();
+}
+
+void
+main_loop(void)
+{
+  static gc_job_desc_t jd;     // static gets us proper alignment
+  gc_eaddr_t   jd_ea;
+
+  // setup events
+  spu_writech(SPU_WrEventMask, MFC_LLR_LOST_EVENT);
+  gc_jd_queue_getllar(spu_args.queue); // get a line reservation on the queue
+
+  while (1){
+
+    if (unlikely(spu_readchcnt(SPU_RdEventStat))){
+      //
+      // execute standard event handling protocol prologue
+      //
+      int status = spu_readch(SPU_RdEventStat);
+      int mask = spu_readch(SPU_RdEventMask);
+      spu_writech(SPU_WrEventMask, mask & ~status);    // disable active events
+      spu_writech(SPU_WrEventAck, status);             // ack active events
+
+      // execute per-event actions
+
+      if (status & MFC_LLR_LOST_EVENT){
+       //
+       // We've lost a line reservation.  This is most likely caused
+       // by somebody doing something to the queue.  Go look and see
+       // if there's anything for us.
+       //
+       if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd))
+         process_job(jd_ea, &jd);
+
+       gc_jd_queue_getllar(spu_args.queue);    // get a new reservation
+      }
+
+      //
+      // execute standard event handling protocol epilogue
+      //
+      spu_writech(SPU_WrEventMask, mask);      // restore event mask
+    }
+
+    // FIXME we could handle these via events too
+
+    // any msgs for us?
+
+    if (unlikely(spu_readchcnt(SPU_RdInMbox))){
+      int msg = spu_readch(SPU_RdInMbox);
+      // printf("spu[%d] mbox_msg: 0x%08x\n", spu_args.spu_idx, msg);
+      if (MBOX_MSG_OP(msg) == OP_EXIT){
+       flush_completion_info();
+       return;
+      }
+    }
+
+    // If we've got job completion info for the PPE and we can send a
+    // message without blocking, do it.
+
+    if (comp_info.ncomplete != 0 && spu_readchcnt(SPU_WrOutIntrMbox) != 0)
+      flush_completion_info();
+  }
+}
+
+
+int 
+main(unsigned long long spe_id __attribute__((unused)),
+     unsigned long long argp,
+     unsigned long long envp __attribute__((unused)))
+{
+  sys_tags_init();
+  ci_tags = mfc_multi_tag_reserve(2);
+
+  // dma the args in
+  mfc_get(&spu_args, argp, sizeof(spu_args), sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << sys_tag);    // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  backoff_init();              // initialize backoff parameters
+
+  main_loop();
+  return 0;
+}

Deleted: gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c

Modified: gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h 
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h 
2008-02-13 23:05:09 UTC (rev 7665)
@@ -42,6 +42,15 @@
 bool
 gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item);
 
+
+/*!
+ * \brief Get a line reservation on the queue
+ *
+ * \param[in]  q is EA address of queue structure.
+ */
+void
+gc_jd_queue_getllar(gc_eaddr_t q);
+
 __GC_END_DECLS
 
 





reply via email to

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