コード例 #1
0
ファイル: lock.c プロジェクト: t-crest/patmos
void acquire_lock(LOCK_T * lock){
    /* Write Entering true */
    /* Write Number */
    unsigned remote = lock->remote_cpuid;
    unsigned id = get_cpuid();
    lock->local_entering = 1;
    
    noc_write(remote,
              (void _SPM *)&(lock->remote_ptr->remote_entering),
              (void _SPM *)&lock->local_entering,
              sizeof(lock->local_entering),
              0);

    //#pragma loopbound min 1 max 2
    #pragma loopbound min PKT_TRANS_WAIT max PKT_TRANS_WAIT
    while(!noc_dma_done(remote));
    unsigned n = (unsigned)lock->remote_number + 1;
    lock->local_number = n;
    /* Enforce memory barrier */
    noc_write(remote,
              (void _SPM *)&(lock->remote_ptr->remote_number),
              (void _SPM *)&lock->local_number,
              sizeof(lock->local_number),
              0);

//    /* Enforce memory barrier */
    #pragma loopbound min PKT_TRANS_WAIT max PKT_TRANS_WAIT
    while(!noc_dma_done(remote)); // noc_write() also waits for the dma to be
                                // free, so no need to do it here as well

    /* Write Entering false */
    lock->local_entering = 0;
    noc_write(remote,
              (void _SPM *)&(lock->remote_ptr->remote_entering),
              (void _SPM *)&lock->local_entering,
              sizeof(lock->local_entering),
              0);

    /* Wait for remote core not to change number */
    #pragma loopbound min 1 max 2
    while(lock->remote_entering == 1);
    /* Wait to be the first in line to the bakery queue */
    unsigned m = lock->remote_number;
    #pragma loopbound min 1 max 2
    while( (m != 0) &&
            ( (m < n) || ((m == n) && ( remote < id)))) {
      m = lock->remote_number;
    }
    /* Lock is grabbed */  
    return;
}
コード例 #2
0
void noc_test_slave() {
  // Performing libnoc test...
  noc_receive();
  // for (int i = 0; i < 8; ++i) {
  //   *(NOC_SPM_BASE+i) = 0x11223344 * i;
  // }
  noc_write((unsigned)NOC_MASTER,(volatile void _SPM *)(NOC_SPM_BASE+(get_cpuid()*8)),(volatile void _SPM *)NOC_SPM_BASE,32,1);

  while(done[NOC_MASTER] != 1){;}

  return;
}
コード例 #3
0
ファイル: lock.c プロジェクト: t-crest/patmos
void release_lock(LOCK_T * lock) {
    /* Write Number */
    lock->local_number = 0;
    noc_write(lock->remote_cpuid,
              (void _SPM *)&(lock->remote_ptr->remote_number),
              (void _SPM *)&lock->local_number,
              sizeof(lock->local_number),
              0);
    /* Enforce memory barrier */
    #pragma loopbound min PKT_TRANS_WAIT max PKT_TRANS_WAIT
    while(!noc_dma_done(lock->remote_cpuid));
    /* Lock is freed */  
    return;
}
コード例 #4
0
void noc_test_master() {
  printf("Performing libnoc test...");
  fflush(stdout);
  for (int i = 0; i < get_cpucnt(); ++i) {
    if (i != NOC_MASTER) {
      for (int j = 0; j < 8; ++j) {
        *(NOC_SPM_BASE+j) = 0x11223344 * i;
      }
      noc_write((unsigned)i,(volatile void _SPM *)NOC_SPM_BASE,(volatile void _SPM *)NOC_SPM_BASE,32,1); 
      while(done[i] != 1){;}
      noc_receive();
      for (int j = 0; j < 8; ++j){
        ABORT_IF_FAIL(*(NOC_SPM_BASE+(i*8)+j) != 0x11223344 * i ,"Wrong data received");
      }
    }
  }
  printf("OK\n");
}
コード例 #5
0
static void slave(void* param) {
  // clear communication areas
  // cannot use memset() for _SPM pointers!
  for(int i = 0; i < sizeof(struct msg_t); i++) {
    ((volatile _SPM char *)spm_in)[i] = 0;
    ((volatile _SPM char *)spm_out)[i] = 0;
  }

  // wait and poll until message arrives
  while(!spm_in->ready) {
    /* spin */
  }

  // PROCESS: add ID to sum_id
  spm_out->sum = spm_in->sum + get_cpuid();
  spm_out->ready = 1;

  // send to next slave
  int rcv_id = (get_cpuid()==(get_cpucnt()-1)) ? 0 : get_cpuid()+1;
  noc_write(rcv_id, spm_in, spm_out, sizeof(struct msg_t), 0);

  return;
}
コード例 #6
0
static void master(void) {

  // reset sum
  spm_out->sum = 0;
  // the message is ready
  spm_out->ready = 1;

  // The first message must be delayed until all slaves have cleared
  // their SPM! Writing something does the trick.
  WRITE("INIT\n", 5);

  // send message to core 1
  noc_write(get_cpuid()+1, spm_in, spm_out, sizeof(struct msg_t), 0);

  WRITE("SENT\n", 5);

  // wait and poll
  while(!spm_in->ready) {
    /* spin */
  }

  WRITE("RCVD ", 5);

  static char msg[10];
  msg[0] = XDIGIT((spm_in->sum >> 28) & 0xf);
  msg[1] = XDIGIT((spm_in->sum >> 24) & 0xf);
  msg[2] = XDIGIT((spm_in->sum >> 20) & 0xf);
  msg[3] = XDIGIT((spm_in->sum >> 16) & 0xf);
  msg[4] = XDIGIT((spm_in->sum >> 12) & 0xf);
  msg[5] = XDIGIT((spm_in->sum >>  8) & 0xf);
  msg[6] = XDIGIT((spm_in->sum >>  4) & 0xf);
  msg[7] = XDIGIT((spm_in->sum >>  0) & 0xf);
  msg[8] = '\n';
  WRITE(msg, 9);

  return;
}