#ifndef _include_comm_h_
#define _include_comm_h_

#ifdef COMM_GASNET
  #define ti_write_sync() IF_DISTGC( {tic_write_sync();gasnet_wait_syncnbi_puts();}, \
                                     gasnet_wait_syncnbi_puts())
  #define ti_read_sync()  IF_DISTGC( {tic_read_sync();gasnet_wait_syncnbi_gets();}, \
                                     gasnet_wait_syncnbi_gets())
  #define ti_sync()       IF_DISTGC( {tic_sync();gasnet_wait_syncnbi_all();}, \
                                     gasnet_wait_syncnbi_all())

  /* forced to use AM for safety when dist. GC is enabled */
  #define ti_bulk_read(d_addr, s_box, s_addr, size, ptr_embedding) do {             \
      ti_srcpos();                                                                  \
      if (ptr_embedding == tic_no_ptrs)                                             \
        gasnet_get_bulk(d_addr, s_box, s_addr, size);                               \
      else                                                                          \
        IF_DISTGC({TI_TRACE_AMGETPTR(toglobalb(s_box, s_addr),size);                \
                  bulk_read(d_addr, toglobalb(s_box, s_addr), size, ptr_embedding);}, \
                  gasnet_get_bulk(d_addr, s_box, s_addr, size));                    \
    } while(0)
  #define ti_bulk_read_weak(d_addr, s_box, s_addr, size, ptr_embedding) do {       \
      ti_srcpos();                                                                 \
      if (ptr_embedding == tic_no_ptrs)                                            \
        gasnet_get_nbi_bulk(d_addr, s_box, s_addr, size);                          \
      else                                                                         \
        IF_DISTGC({TI_TRACE_AMGETPTR(toglobalb(s_box, s_addr),size);               \
                  bulk_get(d_addr, toglobalb(s_box, s_addr), size, ptr_embedding);}, \
                  gasnet_get_nbi_bulk(d_addr, s_box, s_addr, size));               \
    } while(0)

  #define ti_bulk_write(d_box, d_addr, s_addr, size) do { \
    ti_srcpos();                                          \
    gasnet_put_bulk(d_box, d_addr, s_addr, size);         \
   } while(0)
  /* GASNet put_bulk_nbi semantics require the source memory to remain unchanged until sync */
  #define ti_bulk_write_weak(d_box, d_addr, s_addr, size) do { \
    ti_srcpos();                                               \
    gasnet_put_nbi(d_box, d_addr, s_addr, size);               \
   } while(0)
#else
  #define ti_write_sync() tic_write_sync()
  #define ti_read_sync()  tic_read_sync()
  #define ti_sync()       tic_sync()

  #define ti_bulk_read(d_addr, s_box, s_addr, size, ptr_embedding) \
    bulk_read(d_addr, toglobalb(s_box, s_addr), size, ptr_embedding)
  #define ti_bulk_read_weak(d_addr, s_box, s_addr, size, ptr_embedding) \
    bulk_get(d_addr, toglobalb(s_box, s_addr), size, ptr_embedding)

  #define ti_bulk_write(d_box, d_addr, s_addr, size) \
    bulk_write(toglobalb(d_box, d_addr), s_addr, size)
  #define ti_bulk_write_weak(d_box, d_addr, s_addr, size) \
    bulk_put(toglobalb(d_box, d_addr), s_addr, size)
#endif

#endif /* _include_comm_h_ */