⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread-packets.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:



static char * unpack_string(
                            char * src,
                            char * dest,
                            int length)
{
  while (length--) *dest++ = *src++ ;
  *dest = '\0' ;
  return src ;
} /* unpack_string */


void output_threadid(char * title,threadref * ref)
{
  char hexid[20] ;
  pack_threadid(&hexid[0],ref) ; /* Convert threead id into hex */
  hexid[16] = 0 ;
  output_string(title) ; 
  output_string(&hexid[0]) ; 
  output_string("\n") ;
}

/* ------ REMOTE_UPK_THREAD_INFO_RESPONSE ------------------------------- */
/* Unpack the response of a detailed thread info packet */
/* Encoding:  i'Q':8,i'R':8,argmask:16,threadid:64,(tag:8,length:16,data:x)* */

#define TAG_THREADID 1
#define TAG_EXISTS 2
#define TAG_DISPLAY 4
#define TAG_THREADNAME 8
#define TAG_MOREDISPLAY 16 


int remote_upk_thread_info_response(
                               char * pkt,
                               threadref * expectedref ,
                               struct gdb_ext_thread_info * info)
{
  int mask, length ;
  unsigned int tag ;
  threadref ref ;
  char * limit = pkt + 500 ; /* plausable parsing limit */
  int retval = 1 ;

  PKT_TRACE("upk-threadinfo ",pkt) ;

  /* info->threadid = 0 ; FIXME: implement zero_threadref */
  info->active = 0 ;
  info->display[0] = '\0' ;
  info->shortname[0] = '\0' ;
  info->more_display[0] = '\0' ;

  /* Assume the characters indicating the packet type have been stripped */
  pkt = unpack_int(pkt,&mask) ;  /* arg mask */
  pkt = unpack_threadid(pkt , &ref) ;
                      
  if (! threadmatch(&ref,expectedref))
    { /* This is an answer to a different request */
      output_string("FAIL Thread mismatch\n") ;
      output_threadid("ref ",&ref) ;
      output_threadid("expected ",expectedref) ;
      return 0 ;
    }
  copy_threadref(&info->threadid,&ref) ;
  
  /* Loop on tagged fields , try to bail if somthing goes wrong */
  if (mask==0)  output_string("OOPS NO MASK \n") ;

  while ((pkt < limit) && mask && *pkt)  /* packets are terminated with nulls */
    {
      pkt = unpack_int(pkt,&tag) ;            /* tag */
      pkt = unpack_byte(pkt,&length) ;   /* length */
      if (! (tag & mask))  /* tags out of synch with mask */
        {
          output_string("FAIL: threadinfo tag mismatch\n") ;
          retval = 0 ;
          break ;
        }
      if (tag == TAG_THREADID)
        {
          output_string("unpack THREADID\n") ;
          if (length != 16)
            {
              output_string("FAIL: length of threadid is not 16\n") ;
              retval = 0 ;
              break ;
            }
          pkt = unpack_threadid(pkt,&ref) ;
          mask = mask & ~ TAG_THREADID ;
          continue ;
        }
      if (tag == TAG_EXISTS)
        {
          info->active = stub_unpack_int(pkt,length) ;
          pkt += length ;
          mask = mask & ~(TAG_EXISTS) ;
          if (length > 8)
            {
              output_string("FAIL: 'exists' length too long\n") ;
              retval = 0 ;
              break ;
            }
          continue ;
        }
      if (tag == TAG_THREADNAME)
        {
          pkt = unpack_string(pkt,&info->shortname[0],length) ;
          mask = mask & ~TAG_THREADNAME ;
          continue ;
        }
      if (tag == TAG_DISPLAY)
        { 
          pkt = unpack_string(pkt,&info->display[0],length) ;
          mask = mask & ~TAG_DISPLAY ;
          continue ;
        }
      if (tag == TAG_MOREDISPLAY)
        { 
          pkt = unpack_string(pkt,&info->more_display[0],length) ;
          mask = mask & ~TAG_MOREDISPLAY ;
          continue ;
        }
      output_string("FAIL: unknown info tag\n") ;
      break ; /* Not a tag we know about */
    }
  return retval  ;
} /* parse-thread_info_response */


/* ---- REMOTE_PACK_CURRTHREAD_REQUEST ---------------------------- */
/* This is a request to emit the T packet */

/* FORMAT: 'q':8,'C' */

char * remote_pack_currthread_request(char * pkt )
{
  *pkt++ = 'q' ;
  *pkt++ = 'C' ;
  *pkt = '\0' ;
  return pkt ;
} /* remote_pack_currthread_request */


/* ------- REMOTE_UPK_CURTHREAD_RESPONSE ----------------------- */
/* Unpack the interesting part of a T packet */


int remote_upk_currthread_response(
                               char * pkt,
                               int *thr )  /* Parse a T packet */
{
  int retval = 0 ;
  PKT_TRACE("upk-currthreadresp ",pkt) ;

#if 0
  {
    static char threadtag[8] =  "thread" ;
    int retval = 0 ;
    int i , found ;
    char ch ;
    int quickid ;

  /* Unpack as a t packet */
  while (((ch = *pkt++) != ':')    /* scan for : thread */
         && (ch != '\0'))          /* stop at end of packet */

    {
      found = 0 ;
      i = 0 ;
      while ((ch = *pkt++) == threadtag[i++]) ;
      if (i == 8) /* string match "thread" */
        {
          pkt = unpack_varlen_hex(pkt,&quickid) ;
          retval = 1;
          break ;
        }
      retval = 0 ;
    }
  }
#else
  pkt = unpack_threadid(pkt, thr) ;
  retval = 1 ;
#endif  
  return retval ;
} /* remote_upk_currthread_response */


/* -------- REMOTE_UPK-SIMPLE_ACK --------------------------------- */
/* Decode a response which is eother "OK" or "Enn"
   fillin error code,  fillin pkfag-1== undef, 0==nak, 1 == ack ;
   return advanced packet pointer */


char * remote_upk_simple_ack(
                             char * buf,
                             int * pkflag,
                             int * errcode)
{
  int lclerr = 0 ;
  char ch = *buf++ ;
  int retval = -1 ;  /* Undefined ACK , a protocol error */
  if (ch == 'E')     /* NAK */
    {
      buf = unpack_byte(buf,&lclerr) ;
      retval = 0 ;   /* transaction failed, explicitly */
    }
  else
    if ((ch == 'O') && (*buf++ == 'K')) /* ACK */
      retval = 1 ; /* transaction succeeded */
  *pkflag = retval ;
  *errcode = lclerr ;
  return buf ;
} /* remote-upk_simple_ack */


/* -------- PACK_THREADALIVE_REQUEST ------------------------------- */

char * pack_threadalive_request(
                         char * buf,
                         threadref * threadid)
{
  *buf++ = 'T' ;
  buf = pack_threadid(buf,threadid) ;
  *buf = '\0' ;
  return buf ;
} /* pack_threadalive_request */
     
#endif /* GDB_MOCKUP */

/* ---------------------------------------------------------------------- */
/* UNIT_TESTS SUBSECTION                                                  */
/* ---------------------------------------------------------------------- */


#if UNIT_TEST
extern void output_string(char * message) ;
static char test_req[400] ;
static char t_response[400] ;



/* ----- DISPLAY_THREAD_INFO ---------------------------------------------- */
/*  Use local cygmon string output utiities */

void display_thread_info(struct gdb_ext_thread_info * info)
{

  output_threadid("Threadid: ",&info->threadid) ;
  /* short name */
  output_string("Name: ") ; output_string(info->shortname) ; output_string("\n");
  /* format display state */
  output_string("State: ") ; output_string(info->display) ; output_string("\n") ;
  /* additional data */
  output_string("other: ");output_string(info->more_display);
   output_string("\n\n");
} /* display_thread_info */


/* --- CURRTHREAD-TEST -------------------------------------------- */
static int currthread_test(threadref * thread)
{
  int result ;
  int threadid ;
  output_string("TEST: currthread\n") ;
  remote_pack_currthread_request(test_req) ;
  stub_pkt_currthread(test_req+2,t_response,STUB_BUF_MAX) ;
  result = remote_upk_currthread_response(t_response+2, &threadid) ;
  if (result)
    {
      output_string("PASS getcurthread\n") ;
      /* FIXME: print the thread */
    }
  else
    output_string("FAIL getcurrthread\n") ;
  return result ;
} /* currthread_test */

/* ------ SETTHREAD_TEST ------------------------------------------- */
  /* use a known thread from previous test */

static int setthread_test(threadref * thread)
{
  int result, errcode ;
  output_string("TEST: setthread\n") ;
  
  pack_setthread_request(test_req,'p',1,thread) ;
  stub_pkt_changethread(test_req,t_response,STUB_BUF_MAX) ;
  remote_upk_simple_ack(t_response,&result,&errcode) ;
  switch (result)
    {
    case 0 :
      output_string("FAIL setthread\n") ;
      break ;
    case 1 :
      output_string("PASS setthread\n") ;
      break ;
    default :
      output_string("FAIL setthread -unrecognized response\n") ;
      break ;
    }
  return result ;
} /* setthread_test */


/* ------ THREADACTIVE_TEST ---------------------- */
  /* use known thread */
  /* pack threadactive packet */
  /* process threadactive packet */
  /* parse threadactive response */
  /* check results */


int threadactive_test(threadref * thread)
{
  int result ;
  int errcode ;
  output_string("TEST: threadactive\n") ;
  pack_threadalive_request(test_req,thread) ;
  stub_pkt_thread_alive(test_req+1,t_response,STUB_BUF_MAX);
  remote_upk_simple_ack(t_response,&result,&errcode) ;
  switch (result)
    {
    case 0 :
      output_string("FAIL threadalive\n") ;
      break ;
    case 1 :
      output_string("PASS threadalive\n") ;
      break ;
    default :
      output_string("FAIL threadalive -unrecognized response\n") ;
      break ;
    }
  return result ;
} /* threadactive_test */

/* ------ REMOTE_GET_THREADINFO -------------------------------------- */
int remote_get_threadinfo(
                           threadref * threadid,
                           int fieldset , /* TAG mask */
                           struct gdb_ext_thread_info * info
                          )
{
  int result ;
  pack_threadinfo_request(test_req,fieldset,threadid) ;
  stub_pkt_getthreadinfo(test_req+2,t_response,STUB_BUF_MAX) ;
  result = remote_upk_thread_info_response(t_response+2,threadid,info) ;
  return result ;
} /* remote_get-thrreadinfo */


static struct gdb_ext_thread_info test_info ;

static int get_and_display_threadinfo(threadref * thread)
{
  int mode ;
  int result ;
  /* output_string("TEST: get and display threadinfo\n") ; */

  mode = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
    | TAG_MOREDISPLAY | TAG_DISPLAY ;
  result = remote_get_threadinfo(thread,mode,&test_info) ;
  if (result) display_thread_info(&test_info) ;
#if 0  /* silent subtest */
  if (result)
      output_string("PASS: get_and_display threadinfo\n") ;
  else
      output_string("FAIL: get_and_display threadinfo\n") ;
#endif  
  return result ;
} /* get-and-display-threadinfo */



/* ----- THREADLIST_TEST ------------------------------------------ */
#define TESTLISTSIZE 16
#define TLRSIZ 2
static threadref test_threadlist[TESTLISTSIZE] ;

static int threadlist_test(void)
{
  int done, i , result_count ;
  int startflag = 1 ;
  int result = 1 ;
  int loopcount = 0 ;
  static threadref nextthread ;
  static threadref echo_nextthread ;

  output_string("TEST: threadlist\n") ;

  done = 0 ;
  while (! done)
    {
      if (loopcount++ > 10)
        {
          result = 0 ;
          output_string("FAIL: Threadlist test -infinite loop-\n") ;
          break ;
        }
      pack_threadlist_request(test_req,startflag,TLRSIZ,&nextthread) ;
      startflag = 0 ; /* clear for later iterations */
      stub_pkt_getthreadlist(test_req+2,t_response,STUB_BUF_MAX);
      result_count = parse_threadlist_response(t_response+2,
                                               &echo_nextthread,
                                               &test_threadlist[0],&done) ;
      if (! threadmatch(&echo_nextthread,&nextthread))
        {
          output_string("FAIL: threadlist did not echo arg thread\n");
          result = 0 ;
          break ;
        }
      if (result_count <= 0)
        {
          if (done != 0)
              { output_string("FAIL threadlist_test, failed to get list");
                result = 0 ;
              }
          break ;
        }
      if (result_count > TLRSIZ)
        {
          output_string("FAIL: threadlist response longer than requested\n") ;
          result = 0 ;
          break ;
        }
      /* Setup to resume next batch of thread references , set nestthread */
      copy_threadref(&nextthread,&test_threadlist[result_count-1]) ;
      /* output_threadid("last-of-batch",&nextthread) ; */
      i = 0 ;
      while (result_count--)
          {
            if (0)  /* two display alternatives */
              output_threadid("truncatedisplay",&test_threadlist[i++]) ;
            else
              get_and_display_threadinfo(&test_threadlist[i++]) ; 
          }

    }
  if (!result)
    output_string("FAIL: threadlist test\n") ;
  else output_string("PASS: Threadlist test\n") ;
  return result ;
} /* threadlist_test */


static threadref testthread ;


int test_thread_support(void)
{
  int result = 1 ;
  output_string("TESTING Thread support infrastructure\n") ;
  stub_pack_Tpkt_threadid(test_req) ;
  PKT_TRACE("packing the threadid  -> ",test_req) ;
  result &= currthread_test(&testthread) ;
  result &= get_and_display_threadinfo(&testthread) ;
  result &= threadlist_test() ;
  result &= setthread_test(&testthread) ;
  if (result)
    output_string("PASS: UNITTEST Thread support\n") ;
  else
        output_string("FAIL: UNITTEST Thread support\n") ;
  return result ;
} /* test-thread_support */
#endif /* UNIT_TEST */

// #ifdef __ECOS__
#endif // ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT...
// #endif // __ECOS__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -