How can using a channel violate parallel usage rules?

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

How can using a channel violate parallel usage rules?

Postby gerrykurz » Tue Jul 21, 2015 7:57 am

Here are the compiler error messages:
../src/main.xc:305:3: error: use of `usage.anon.38' violates parallel usage rules
par
^~~
D:/CSSD Documents/XMOS/Workspace/500 Rack Application/V0-4/lib_ethernet/src/mii_ethernet_rt_mac.xc:394:7: note: object used here
global_tile_id = get_tile_id_from_chanend(c_macaddr_filter);
^~~~~~~~~~~~~~
called by usage.anon.39
called by mii_ethernet_rt_mac
called by usage.anon.169
D:/CSSD Documents/XMOS/Workspace/500 Rack Application/V0-4/lib_ethernet/src/mii_ethernet_rt_mac.xc:394:7: note: object used here
global_tile_id = get_tile_id_from_chanend(c_macaddr_filter);
^~~~~~~~~~~~~~
called by usage.anon.39
called by mii_ethernet_rt_mac
called by usage.anon.163
../src/main.xc:305:3: error: use of `usage.anon.23' violates parallel usage rules
par
^~~
D:/CSSD Documents/XMOS/Workspace/500 Rack Application/V0-4/lib_ethernet/src/mii_filter.xc:68:19: note: object used here
c_conf :> local_tile_id;
^~~~~~~~~~~~~
called by mii_ethernet_rt_mac
called by usage.anon.169
D:/CSSD Documents/XMOS/Workspace/500 Rack Application/V0-4/lib_ethernet/src/mii_filter.xc:68:19: note: object used here
c_conf :> local_tile_id;
^~~~~~~~~~~~~
called by mii_ethernet_rt_mac
called by usage.anon.163
xmake[1]: *** [bin//500RACK.xe] Error 1
xmake: *** [bin//500RACK.xe] Error 2
The first part refers to this par statement:

Code: Select all

par
  {
      on tile[1]: mii_ethernet_rt_mac(i_eth_cfg, NUM_ETH_CFG_CLIENTS,
                                      i_eth_rx_lp, NUM_ETH_RX_LP_CLIENTS,
                                      i_eth_tx_lp, NUM_ETH_TX_LP_CLIENTS,
                                      c_eth_rx_hp, c_eth_tx_hp,
                                      p_eth_rxclk, p_eth_rxerr,
                                      p_eth_rxd, p_eth_rxdv,
                                      p_eth_txclk, p_eth_txen, p_eth_txd,
                                      eth_rxclk, eth_txclk,
                                      ETH_RX_BUFFER_SIZE_WORDS,
                                      ETH_TX_BUFFER_SIZE_WORDS,
                                      ETHERNET_ENABLE_SHAPER);
Then in the real time mac code, I have added this global_tile_id variable:

Code: Select all

    case i_cfg[int i].get_tile_id_and_timer_value(unsigned &tile_id, unsigned &time_on_tile): {
      tile_id = get_tile_id_from_chanend(c_macaddr_filter);
      global_tile_id = get_tile_id_from_chanend(c_macaddr_filter);

      timer tmr;
      tmr :> time_on_tile;
      break;
and this:

Code: Select all

static unsigned int global_tile_id = 0;
The real time mac has this par statement which creates a channel between the ethernet server and the ethernet filter:

Code: Select all

chan c_conf;
    par {
      mii_master_rx_pins(rx_mem,
                         (mii_packet_queue_t)&incoming_packets,
                         p_rx_rdptr,
                         p_rxdv, p_rxd, p_rxer, c);

      mii_master_tx_pins(tx_mem_lp,
                         tx_mem_hp,
                         (mii_packet_queue_t)&tx_packets_lp,
                         (mii_packet_queue_t)&tx_packets_hp,
                         ts_queue, p_txd,
                         p_port_state);

      mii_ethernet_filter(c, c_conf,
                          (mii_packet_queue_t)&incoming_packets,
                          (mii_packet_queue_t)&rx_packets_lp,
                          (mii_packet_queue_t)&rx_packets_hp);

      mii_ethernet_server(rx_mem,
                          (mii_packet_queue_t)&rx_packets_lp,
                          (mii_packet_queue_t)&rx_packets_hp,
                          p_rx_rdptr,
                          tx_mem_lp,
                          tx_mem_hp,
                          (mii_packet_queue_t)&tx_packets_lp,
                          (mii_packet_queue_t)&tx_packets_hp,
                          ts_queue,
                          i_cfg, n_cfg,
                          i_rx_lp, n_rx_lp,
                          i_tx_lp, n_tx_lp,
                          c_rx_hp,
                          c_tx_hp,
                          c_conf,
                          p_port_state);
    }
so then I use the channel to send the global_tile_id from the server to the filter:

Code: Select all

    case i_cfg[int i].add_macaddr_filter(size_t client_num, int is_hp,
                                         ethernet_macaddr_filter_t entry) ->
                                           ethernet_macaddr_filter_result_t result:
      unsafe {
        c_macaddr_filter <: 0;
        eth_global_filter_info_t * unsafe p;
        c_macaddr_filter :> p;
        result = ethernet_add_filter_table_entry(*p, client_num, is_hp, entry);
        c_macaddr_filter <: global_tile_id;
      }
      break;

Code: Select all

    case c_conf :> int:
      // Give the routing table to the ethernet server to reconfigure
      unsafe {
        eth_global_filter_info_t * unsafe  p = &filter_info;
        c_conf <: p;
        c_conf :> local_tile_id;
      }
      break;
Where local_tile_id is defined in the ethernet filter as:

Code: Select all

static unsigned int local_tile_id = 0;
So what is wrong with this?

How can sending data on a channel violate parallel usage rules?

Any other ideas how I can get the tile id into the mii_filter?
User avatar
ers35
Active Member
Posts: 62
Joined: Mon Jun 10, 2013 2:14 pm

Postby ers35 » Tue Jul 21, 2015 3:37 pm

I do not believe this has anything to do with using a channel. This is due to the use of static variables within a function used multiple times within a par statement. Rewrite the code to not require the use of static variables.

See this example:

Code: Select all

// xcc -target=XCORE-200-EXPLORER par-static.xc
// par-static.xc:17:3: error: use of `usage.anon.3' violates parallel usage rules

#include <platform.h>
#include <xs1.h>

void
test()
{
  static int x;
  x = 1;
}

int
main()
{
  par
  {
    on tile[0]:
    {
      test();
    }
    
    on tile[1]:
    {
      test();
    }
  }
  
  return 0;
}
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Postby gerrykurz » Wed Jul 22, 2015 6:20 am

As usual sir, you were correct.....thanks

Who is online

Users browsing this forum: No registered users and 4 guests