Пример #1
0
inline void mcapi_sclchan_send(
    MCAPI_IN mcapi_sclchan_send_hndl_t send_handle, 
    MCAPI_IN mcapi_uint64_t dataword,
    MCAPI_OUT mcapi_status_t* mcapi_status,
    size_t bytes)
{
    //check for initialization
    if ( mcapi_trans_initialized() == MCAPI_FALSE )
    {
        //no init means failure
        *mcapi_status = MCAPI_ERR_NODE_NOTINIT;
        return;
    }

    //critical section for endpoint begins here
    LOCK_CHANNEL( send_handle );

    //handle must be valid send handle
    if ( !mcapi_trans_valid_sclchan_send_handle(send_handle) )
    {
        *mcapi_status = MCAPI_ERR_CHAN_INVALID;
    }
    else
    {
        //POSIX will handle the rest, timeout of sending endpoint is used
        //priority is fixed to that expected of channel traffic
        *mcapi_status = pmq_send( send_handle.us->chan_msgq_id,
        (void*)&dataword, bytes, MCAPI_MAX_PRIORITY+1,
        send_handle.us->time_out );
    }

    //critical section ends
    UNLOCK_CHANNEL( send_handle );
}
Пример #2
0
mcapi_uint_t mcapi_sclchan_available(
MCAPI_IN mcapi_sclchan_recv_hndl_t receive_handle,
MCAPI_OUT mcapi_status_t* mcapi_status )
{
    //return value
    mcapi_uint_t to_ret = MCAPI_NULL;

    //check for initialization
    if ( mcapi_trans_initialized() == MCAPI_FALSE )
    {
        //no init means failure
        *mcapi_status = MCAPI_ERR_NODE_NOTINIT;
        return MCAPI_NULL;
    }

    LOCK_CHANNEL( receive_handle );

    //handle must be valid
    if ( !mcapi_trans_valid_sclchan_recv_handle( receive_handle ) )
    {
        *mcapi_status = MCAPI_ERR_CHAN_INVALID;
    }
    else
    {
        to_ret = pmq_avail( receive_handle.us->chan_msgq_id, mcapi_status );
    }

    UNLOCK_CHANNEL( receive_handle );

    return to_ret;
}
Пример #3
0
inline mcapi_uint64_t mcapi_sclchan_recv(
    MCAPI_IN mcapi_sclchan_recv_hndl_t receive_handle,
    MCAPI_OUT mcapi_status_t* mcapi_status,
    size_t bytes)
{
    //the priority obtained
    unsigned msg_prio;
    //the received value
    mcapi_uint64_t value = -1;
    //how long message we got in bytes
    size_t mslen;

    //check for initialization
    if ( !mcapi_trans_initialized() )
    {
        //no init means failure
        *mcapi_status = MCAPI_ERR_NODE_NOTINIT;
        return -1;
    }

    LOCK_CHANNEL( receive_handle );

    //handle must be valid
    if ( !mcapi_trans_valid_sclchan_recv_handle(receive_handle) )
    {
        *mcapi_status = MCAPI_ERR_CHAN_INVALID;
    }
    else
    {
        //POSIX will handle the recv, timeout of receiving endpoint is used
        *mcapi_status = pmq_recv( receive_handle.us->chan_msgq_id,
        (void*)&value, bytes, &mslen, &msg_prio, receive_handle.us->time_out );
    }

    UNLOCK_CHANNEL( receive_handle );

    return value;
}
Пример #4
0
/**
 * The runtime support for output actions.
 *
 * @param pt the PiThread structure of the thread trying to output
 * @param chan_ref the environment index of the output channel
 * @param chans the acquired channels  (cf. compilation of output try)
 * @param nbchans the number of acquired channels 
 * @param try_result an output variable for the result of the try (ENABLED if output can be performed, DISABLED if not, and COMMIT if a commiment must be recorded).
 * @return the matching input commitment, if any or NULL otherwise.
 */
PICC_Commit * PICC_try_output_action(PICC_PiThread *pt, int chan_ref, PICC_Channel* chans[], int nbchans, PICC_TryResult * try_result) {
  PICC_Channel* out_chan = PICC_channel_of_channel_value(&(pt->env[chan_ref]));

  // acquire the channel, if required
  if (chan_array_add(out_chan, chans, &nbchans)) {
    LOCK_CHANNEL(out_chan);
  }
  
  if(out_chan->global_rc == 1) {
    // if global reference count is one, then pt is the only
    // thread knowing the channel, hence the try is DISABLED.
    *try_result = PICC_TRY_DISABLED;
    return NULL;
  }
  

  PICC_Commit * commit = NULL;
  PICC_CommitStatus ok = PICC_CANNOT_ACQUIRE;
  
  do {
    // search for a valid input commitment
    commit = PICC_fetch_input_commitment(out_chan);
    if(commit == NULL) {
      // if no valid or invalid commitment left, need to 
      // make an output commitment
      *try_result = PICC_TRY_COMMIT;
      return NULL;
    }
  
    // here, we have a candidate input commitment
  
    // try to awake the commiting thread
    do {
      ok = PICC_can_awake(commit->thread, commit);
      
      if(ok == PICC_CANNOT_ACQUIRE) {
        // to avoid contention on thread awaking
        PICC_low_level_yield();
      }
      
    } while(ok == PICC_CANNOT_ACQUIRE);

    // here we have either a valid commitment
    // an an awoken thread, or an invalid commitment
    // that we just removed  (lazy deletion).
    
    if (ok == PICC_VALID_COMMIT) {
      // ok, everything's fine a synchronization will occur
      *try_result = PICC_TRY_ENABLED;
      return commit; // we return the valid commitment
    }

    // otherwise it's invalid and deleted, and we will
    // try to find a further commitment
  } while (!(PICC_commit_list_is_empty(out_chan->incommits)));

  // TODO:  raise a "dead code reached" error
  CRASH_NEW_ERROR(ERR_DEAD_CODE_REACHED);

  return NULL;

}