OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 171 to Rev 172
    Reverse comparison

Rev 171 → Rev 172

/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/hibi_mappings.h
0,0 → 1,27
/*
* hibi_mappings.c
*
* Created on: 10.4.2013
* Author: matilail
*/
 
 
#ifndef __HIBI_MAPPINGS_H__
#define __HIBI_MAPPINGS_H__
 
#define FDEV_COUNT (4)
#define DEVNAME /dev/hibi_pe_dma0
 
// Filenames for hibi endpoints indices are same as MCAPI node ids
const char* dev_names[FDEV_COUNT] = {"/dev/hibi_pe_dma_0/cpu0",
"/dev/hibi_pe_dma_0/cpu1",
"/dev/hibi_pe_dma_0/buttons",
"/dev/hibi_pe_dma_0/leds"};
 
int fdevs[FDEV_COUNT] = {0};
 
const int hibiBaseAddresses[FDEV_COUNT] = {0x01000000, 0x03000000, 0x05000000, 0x07000000};
const int hibiEndAddresses[FDEV_COUNT] = {0x03000000-1, 0x05000000-1, 0x07000000-1, 0x09000000-1};
 
 
#endif
/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/mcapi_config.h
0,0 → 1,148
/* mcapi_config.h. Generated from mcapi_config.h.in by configure. */
/* mcapi_config.h.in. Generated from configure.ac by autoheader. */
 
/**
* This version is edited by hand!
*
* The following values are modified:
* name | new value | old value |
* --------------------------------------------
* MAX_ATTRIBUTES | 8 | 32 |
* MAX_BUFFERS | 64 | 1024 |
* MAX_CHANNELS | 8 | 32 |
* MAX_ENDPOINTS | 8 | 32 |
* MAX_NODES | 8 | 32 |
* MAX_QUEUE_ELEMENTS | 32 | 64 |
*
* And *why* they were edited? The mcapi_database structure
* took a whopping 1290628 bytes from data memory!
* Currently it is "only" 37732 bytes.
*/
 
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
 
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
 
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
 
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
 
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
 
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
 
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
 
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
 
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
 
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
 
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
 
/* Defined and set to $max_attributes. */
#define MAX_ATTRIBUTES 8
 
/* Defined and set to $max_buffers. */
#define MAX_BUFFERS 64
 
/* Defined and set to $max_channels. */
#define MAX_CHANNELS 8
 
/* Defined and set to $max_endpoints. */
#define MAX_ENDPOINTS 8
 
/* Defined and set to $max_msg_size. */
#define MAX_MSG_SIZE 1024
 
/* Defined and set to $max_nodes. */
#define MAX_NODES 8
 
/* Defined and set to $max_pkt_size. */
#define MAX_PKT_SIZE 32
 
/* Defined and set to $max_queue_elements. */
#define MAX_QUEUE_ELEMENTS 32
 
/* Name of package */
#define PACKAGE "mcapi"
 
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
 
/* Define to the full name of this package. */
#define PACKAGE_NAME "mcapi"
 
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "mcapi 0.0.1"
 
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mcapi"
 
/* Define to the home page for this package. */
#define PACKAGE_URL ""
 
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.0.1"
 
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
 
/* Version number of package */
#define VERSION "0.0.1"
 
/* Defined and set to 1 if we're including debug print support. */
#define WITH_DEBUG 0
 
#define DEFAULT_MSG_SIZE 32
 
 
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
 
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT64_T */
 
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
 
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
 
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
 
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint16_t */
 
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
 
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint64_t */
 
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/mcapi_trans.h
0,0 → 1,289
/*
Copyright (c) 2008, The Multicore Association
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
 
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
(3) Neither the name of the Multicore Association nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef TRANSPORT_H
#define TRANSPORT_H
 
#include "mcapi_datatypes.h"
 
/* Error handling philosophy:
mcapi_status_t is handled at the top level shared code in mcapi.c whenever possible. All
functions in the mcapi_trans layer that need to return status, should return a boolean
indicating success or failure. All functions that need to pass back additional info
(such as filling in a handle) should pass that by reference in a parameter.
*/
 
extern void mcapi_trans_set_debug_level (int d);
extern void mcapi_trans_display_state (void* handle);
 
extern mcapi_boolean_t mcapi_trans_get_node_num(mcapi_uint_t* node_num);
extern mcapi_boolean_t mcapi_trans_set_node_num(mcapi_uint_t node_num);
 
/****************** error checking queries *************************/
/* checks if the given node is valid */
extern mcapi_boolean_t mcapi_trans_valid_node(mcapi_uint_t node_num);
 
/* checks to see if the port_num is a valid port_num for this system */
extern mcapi_boolean_t mcapi_trans_valid_port(mcapi_uint_t port_num);
 
/* checks if an enpoint exists on this node for a given port id */
extern mcapi_boolean_t mcapi_trans_endpoint_exists (uint32_t port_id);
 
/* checks if the endpoint handle refers to a valid endpoint */
extern mcapi_boolean_t mcapi_trans_valid_endpoint (mcapi_endpoint_t endpoint);
extern mcapi_boolean_t mcapi_trans_valid_endpoints (mcapi_endpoint_t endpoint1,
mcapi_endpoint_t endpoint2);
 
/* checks if the channel is open for a given endpoint */
extern mcapi_boolean_t mcapi_trans_endpoint_channel_isopen (mcapi_endpoint_t endpoint);
 
/* checks if the channel is open for a given pktchan receive handle */
extern mcapi_boolean_t mcapi_trans_pktchan_recv_isopen (mcapi_pktchan_recv_hndl_t receive_handle) ;
 
/* checks if the channel is open for a given pktchan send handle */
extern mcapi_boolean_t mcapi_trans_pktchan_send_isopen (mcapi_pktchan_send_hndl_t send_handle) ;
 
/* checks if the channel is open for a given sclchan receive handle */
extern mcapi_boolean_t mcapi_trans_sclchan_recv_isopen (mcapi_sclchan_recv_hndl_t receive_handle) ;
 
/* checks if the channel is open for a given sclchan send handle */
extern mcapi_boolean_t mcapi_trans_sclchan_send_isopen (mcapi_sclchan_send_hndl_t send_handle) ;
 
/* checks if the given endpoint is owned by the given node */
extern mcapi_boolean_t mcapi_trans_endpoint_isowner (mcapi_endpoint_t endpoint);
 
/* returns the channel type */
channel_type mcapi_trans_channel_type (mcapi_endpoint_t endpoint);
 
/* checks if the endpoint is connected */
extern mcapi_boolean_t mcapi_trans_channel_connected (mcapi_endpoint_t endpoint);
 
/* checks if this endpoint can be a receive endpoint ie. has not already
been connected as a send endpoint */
extern mcapi_boolean_t mcapi_trans_recv_endpoint (mcapi_endpoint_t endpoint);
 
/* checks if this endpoint can be a send endpoint ie. has not already
been connected as a receive endpoint */
extern mcapi_boolean_t mcapi_trans_send_endpoint (mcapi_endpoint_t endpoint);
 
/* checks if this node has already called initialize */
extern mcapi_boolean_t mcapi_trans_initialized (mcapi_node_t node_id);
 
/* returns the number of endpoints for the calling node */
extern mcapi_uint32_t mcapi_trans_num_endpoints();
 
/* used by msg_send to check if a given priority level is valid */
extern mcapi_boolean_t mcapi_trans_valid_priority(mcapi_priority_t priority);
 
/* checks if this endpoint is connected */
extern mcapi_boolean_t mcapi_trans_connected(mcapi_endpoint_t endpoint);
 
/* checks if the status parameter is valid */
extern mcapi_boolean_t valid_status_param (mcapi_status_t* mcapi_status);
 
/* checks if the version parameter is valid */
extern mcapi_boolean_t valid_version_param (mcapi_version_t* mcapi_version);
 
/* checks if the buffer parameter is valid */
extern mcapi_boolean_t valid_buffer_param (void* buffer);
 
/* checks if the request parameter is valid */
extern mcapi_boolean_t valid_request_param (mcapi_request_t* request);
 
/* checks if the size parameter is valid */
extern mcapi_boolean_t valid_size_param (size_t* size);
 
/* checks if the given endpoints have compatible attributes */
extern mcapi_boolean_t mcapi_trans_compatible_endpoint_attributes
(mcapi_endpoint_t send_endpoint, mcapi_endpoint_t recv_endpoint);
 
/* checks if the given channel handle is valid */
extern mcapi_boolean_t mcapi_trans_valid_pktchan_send_handle( mcapi_pktchan_send_hndl_t handle);
extern mcapi_boolean_t mcapi_trans_valid_pktchan_recv_handle( mcapi_pktchan_recv_hndl_t handle);
extern mcapi_boolean_t mcapi_trans_valid_sclchan_send_handle( mcapi_sclchan_send_hndl_t handle);
extern mcapi_boolean_t mcapi_trans_valid_sclchan_recv_handle( mcapi_sclchan_recv_hndl_t handle);
 
 
/****************** initialization *************************/
/* initialize the transport layer */
extern mcapi_boolean_t mcapi_trans_initialize(mcapi_uint_t node_num);
 
/****************** tear down ******************************/
extern mcapi_boolean_t mcapi_trans_finalize();
 
/****************** endpoints ******************************/
/* create endpoint <node_num,port_num> and return it's handle */
extern mcapi_boolean_t mcapi_trans_create_endpoint(mcapi_endpoint_t *endpoint,
mcapi_uint_t port_num,
mcapi_boolean_t anonymous);
 
/* non-blocking get endpoint for the given <node_num,port_num> and set
endpoint parameter to it's handle */
extern void mcapi_trans_get_endpoint_i( mcapi_endpoint_t* endpoint, mcapi_uint_t node_num,
mcapi_uint_t port_num,mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
/* blocking get endpoint for the given <node_num,port_num> and return it's handle */
extern void mcapi_trans_get_endpoint(mcapi_endpoint_t *endpoint,mcapi_uint_t node_num,
mcapi_uint_t port_num);
 
/* delete the given endpoint */
extern void mcapi_trans_delete_endpoint( mcapi_endpoint_t endpoint);
 
/* get the attribute for the given endpoint and attribute_num */
extern void mcapi_trans_get_endpoint_attribute( mcapi_endpoint_t endpoint,
mcapi_uint_t attribute_num,
void* attribute, size_t attribute_size);
 
/* set the given attribute on the given endpoint */
extern void mcapi_trans_set_endpoint_attribute( mcapi_endpoint_t endpoint,
mcapi_uint_t attribute_num,
const void* attribute, size_t attribute_size);
 
 
/****************** msgs **********************************/
extern void mcapi_trans_msg_send_i( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
char* buffer, size_t buffer_size,
mcapi_request_t* request,mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_msg_send( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
char* buffer, size_t buffer_size);
 
extern void mcapi_trans_msg_recv_i( mcapi_endpoint_t receive_endpoint,
char* buffer, size_t buffer_size,
mcapi_request_t* request,mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_msg_recv( mcapi_endpoint_t receive_endpoint,
char* buffer, size_t buffer_size,
size_t* received_size);
 
extern mcapi_uint_t mcapi_trans_msg_available( mcapi_endpoint_t receive_endoint);
 
/****************** channels general ****************************/
 
/****************** pkt channels ****************************/
extern void mcapi_trans_connect_pktchan_i( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_open_pktchan_recv_i( mcapi_pktchan_recv_hndl_t* recv_handle,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_open_pktchan_send_i( mcapi_pktchan_send_hndl_t* send_handle,
mcapi_endpoint_t send_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_pktchan_send_i( mcapi_pktchan_send_hndl_t send_handle,
void* buffer, size_t size,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_pktchan_send( mcapi_pktchan_send_hndl_t send_handle,
void* buffer, size_t size);
 
extern void mcapi_trans_pktchan_recv_i( mcapi_pktchan_recv_hndl_t receive_handle,
void** buffer, mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_pktchan_recv( mcapi_pktchan_recv_hndl_t receive_handle,
void** buffer, size_t* received_size);
 
extern mcapi_uint_t mcapi_trans_pktchan_available( mcapi_pktchan_recv_hndl_t receive_handle);
 
extern mcapi_boolean_t mcapi_trans_pktchan_free( void* buffer);
 
extern void mcapi_trans_pktchan_recv_close_i( mcapi_pktchan_recv_hndl_t receive_handle,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_pktchan_send_close_i( mcapi_pktchan_send_hndl_t send_handle,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
/****************** scalar channels ****************************/
extern void mcapi_trans_connect_sclchan_i( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_open_sclchan_recv_i( mcapi_sclchan_recv_hndl_t* recv_handle,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_open_sclchan_send_i( mcapi_sclchan_send_hndl_t* send_handle,
mcapi_endpoint_t send_endpoint,
mcapi_request_t* request,
mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_sclchan_send( mcapi_sclchan_send_hndl_t send_handle,
uint64_t dataword, uint32_t size);
 
extern mcapi_boolean_t mcapi_trans_sclchan_recv( mcapi_sclchan_recv_hndl_t receive_handle,
uint64_t *data,uint32_t exp_size);
 
extern mcapi_uint_t mcapi_trans_sclchan_available_i( mcapi_sclchan_recv_hndl_t receive_handle);
 
extern void mcapi_trans_sclchan_recv_close_i( mcapi_sclchan_recv_hndl_t recv_handle,
mcapi_request_t* mcapi_request,
mcapi_status_t* mcapi_status);
 
extern void mcapi_trans_sclchan_send_close_i( mcapi_sclchan_send_hndl_t send_handle,
mcapi_request_t* mcapi_request,
mcapi_status_t* mcapi_status);
 
/****************** test,wait & cancel ****************************/
extern mcapi_boolean_t mcapi_trans_test_i( mcapi_request_t* request, size_t* size,
mcapi_status_t* mcapi_status);
 
extern mcapi_boolean_t mcapi_trans_wait( mcapi_request_t* request, size_t* size,
mcapi_status_t* mcapi_status,
mcapi_timeout_t timeout);
extern mcapi_boolean_t mcapi_trans_wait_any(size_t number, mcapi_request_t** requests, size_t* size,
mcapi_status_t* mcapi_status,
mcapi_timeout_t timeout);
 
extern int mcapi_trans_wait_first( size_t number, mcapi_request_t** requests,
size_t* size);
 
extern void mcapi_trans_cancel( mcapi_request_t* request,mcapi_status_t* mcapi_status);
 
/****************** stats ****************************/
extern void mcapi_trans_display_stats (void* handle);
 
#endif
/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/trans_hibi_fdev.c
0,0 → 1,3529
// **************************************************************************
// File : trans_hibi_fdev.c
// Author : matilail
// Date : 10.04.2013
// Decription : MCAPI transport layer implementation for NIOS II
// With hibi_pe_dma file device
// (modified from The Multicore Association example
// shared memory implementation)
// **************************************************************************
 
 
 
/*
Copyright (c) 2008, The Multicore Association
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
(3) Neither the name of the Multicore Association nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
 
 
 
 
 
#include <string.h> /* for memcpy */
#include <assert.h> /* for assertions */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stddef.h> /* for size_t */
#include "includes.h"
 
#include "mcapi_trans.h" /* the transport API */
#include "trans_hibi_fdev.h"
 
#include <hibi_pe_dma_defines.h>
 
#include "hibi_mappings.h"
 
//////////////////////////////////////////////////////////////////////////////
// //
// Constants and defines //
// //
//////////////////////////////////////////////////////////////////////////////
#define MAGIC_NUM 0xdeadcafe
#define MSG_HEADER 1
#define MSG_PORT 0
 
 
 
 
//////////////////////////////////////////////////////////////////////////////
// //
// Function prototypes (private) //
// //
//////////////////////////////////////////////////////////////////////////////
 
 
mcapi_boolean_t mcapi_trans_decode_handle_internal (uint32_t handle, uint16_t *node_index,
uint16_t *endpoint_index);
 
uint32_t mcapi_trans_encode_handle_internal (uint16_t node_index,uint16_t endpoint_index);
 
void mcapi_trans_signal_handler ( int sig );
 
mcapi_boolean_t mcapi_trans_add_node (mcapi_uint_t node_num);
 
mcapi_boolean_t mcapi_trans_send_internal (uint16_t sn,uint16_t se, uint16_t rn, uint16_t re,
char* buffer, size_t buffer_size,mcapi_boolean_t blocking,uint64_t scalar);
 
mcapi_boolean_t mcapi_trans_recv_internal (uint16_t rn, uint16_t re, void** buffer, size_t buffer_size,
size_t* received_size,mcapi_boolean_t blocking,uint64_t* scalar);
 
void mcapi_trans_recv_internal_ (uint16_t rn, uint16_t re, void** buffer, size_t buffer_size,
size_t* received_size,int qindex,uint64_t* scalar);
 
mcapi_boolean_t mcapi_trans_get_endpoint_internal (mcapi_endpoint_t *e, mcapi_uint_t node_num,
mcapi_uint_t port_num);
 
void mcapi_trans_open_channel_internal (uint16_t n, uint16_t e);
 
void mcapi_trans_close_channel_internal (uint16_t n, uint16_t e);
 
void mcapi_trans_connect_channel_internal (mcapi_endpoint_t send_endpoint, mcapi_endpoint_t receive_endpoint,
channel_type type);
void setup_request_internal (mcapi_endpoint_t* endpoint,mcapi_request_t* request,mcapi_status_t* mcapi_status,
mcapi_boolean_t completed, size_t size,void** buffer,mcapi_request_type type);
 
void check_receive_request (mcapi_request_t *request);
 
void cancel_receive_request (mcapi_request_t *request);
 
void check_get_endpt_request (mcapi_request_t *request);
 
void check_open_request (mcapi_request_t *request);
 
int get_private_data_index ();
 
mcapi_boolean_t mcapi_trans_get_node_index(mcapi_uint_t n);
 
void mcapi_trans_display_state_internal (void* handle);
 
/* queue management */
void print_queue (queue q);
 
int mcapi_trans_pop_queue (queue *q);
 
int mcapi_trans_push_queue (queue *q);
 
mcapi_boolean_t mcapi_trans_empty_queue (queue q);
 
mcapi_boolean_t mcapi_trans_full_queue (queue q);
 
void mcapi_trans_compact_queue (queue* q);
 
mcapi_boolean_t mcapi_trans_create_endpoint_(mcapi_endpoint_t* ep, mcapi_uint_t node_num, mcapi_uint_t port_num,
mcapi_boolean_t anonymous);
 
void transport_sm_yield_internal();
 
 
 
void mcapi_trans_initialize_database();
 
//////////////////////////////////////////////////////////////////////////////
// //
// Data //
// //
//////////////////////////////////////////////////////////////////////////////
 
/* Database for store endpoint and channel information */
mcapi_database c_db_impl;
mcapi_database* c_db = &c_db_impl;
 
/* the debug level */
int mcapi_debug = 0;
 
/* global my node id number */
mcapi_uint_t my_node_id = 255;
 
 
//int cpu0_dev;
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME: mcapi_trans_get_node_num
DESCRIPTION: gets the node_num (not the transport's node index!)
PARAMETERS: node_num: the node_num pointer to be filled in
RETURN VALUE: boolean indicating success (the node num was found) or failure
(couldn't find the node num).
***************************************************************************/
mcapi_boolean_t mcapi_trans_get_node_num(mcapi_uint_t* node)
{
//int i;
/* the database does not need to be locked, but it's okay if it is */
/* The database is locked whenever d[i].pid is set. Here, we're just
reading it. */
 
//i = get_private_data_index();
 
 
//if (d[i].pid == 0) {
// return MCAPI_FALSE;
//} else {
// *node = d[i].node_num;
//}
*node = my_node_id; //LM
return MCAPI_TRUE;
}
 
 
/***************************************************************************
NAME: mcapi_trans_initialize OK
DESCRIPTION: initializes the transport layer
PARAMETERS: node_num: the node number
RETURN VALUE: boolean: success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_initialize(mcapi_uint_t node_num)
{
int i = 0;
mcapi_boolean_t rc = MCAPI_TRUE;
mcapi_trans_initialize_database();
//rc = mcapi_trans_initialize_();
if (rc) {
/* add the node */
rc = mcapi_trans_add_node(node_num);
}
 
my_node_id = node_num;
 
printf("opening devices \n");
for(i = 0; i < FDEV_COUNT ; i++)
{
fdevs[i] = open(dev_names[i], O_RDWR, 0x700);
if (fdevs[i] == -1) rc = MCAPI_FALSE;
 
}
 
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_initialize_database
DESCRIPTION: Initializes the global mcapi_database structure. Does not
initialize buffer contents, but other variables are
initialized.
PARAMETERS: -
RETURN VALUE: -
***************************************************************************/
/**
* NOTICE: The mcapi_database can be *huge* depending on the defines in
* mcapi_config.h. If the processor's data memory is too small for the
* database, this function *will* overwrite heap, stack and/or other
* variables. You have been warned.
*/
void mcapi_trans_initialize_database() {
 
/* initialize the whole mcapi_database */
int i = 0;
c_db->num_nodes = 0;
for (i = 0; i < MAX_NODES; i++) {
int j = 0;
node_entry* node = &(c_db->nodes[i]);
node->node_num = 0;
node->finalized = MCAPI_FALSE; /* TODO: is this the correct value? */
node->valid = MCAPI_FALSE;
node->node_d.num_endpoints = 0;
for (j = 0; j < MAX_ENDPOINTS; j++) {
int k = 0;
endpoint_entry* end = &(node->node_d.endpoints[j]);
end->port_num = 0;
end->valid = MCAPI_FALSE;
end->anonymous = MCAPI_FALSE;
end->open = MCAPI_FALSE;
end->connected = MCAPI_FALSE;
end->num_attributes = 0;
for (k = 0; k < MAX_ATTRIBUTES; k++) {
attribute_entry* attr = &(end->attributes[k]);
attr->valid = MCAPI_FALSE;
attr->attribute_num = 0;
attr->bytes = 0;
attr->attribute_d = NULL;
}
queue* epQueue = &(end->recv_queue);
epQueue->send_endpt = 0;
epQueue->recv_endpt = 0;
epQueue->channel_type = 0;
epQueue->num_elements = 0;
epQueue->head = 0;
epQueue->tail = 0;
for (k = 0; k < MAX_QUEUE_ENTRIES; k++) {
buffer_descriptor* bufferDesc = &(epQueue->elements[k]);
bufferDesc->request = 0;
bufferDesc->b = 0;
bufferDesc->invalid = MCAPI_FALSE;
}
}
}
for (i = 0; i < MAX_BUFFERS; i++) {
buffer_entry* buffer = &(c_db->buffers[i]);
buffer->magic_num = 0;
buffer->size = 0;
buffer->in_use = MCAPI_FALSE;
#ifndef __TCE__
buffer->scalar = 0;
#else
buffer->scalar.hi = 0;
buffer->scalar.lo = 0;
#endif
}
}
 
/***************************************************************************
NAME:mcapi_trans_finalize TODO: file_dev
DESCRIPTION: cleans up the semaphore and shared memory resources.
PARAMETERS: none
RETURN VALUE: boolean: success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_finalize ()
{
int i = 0;
 
// close file devices
for(i = 0; i < FDEV_COUNT; i++)
{
close(fdevs[i]);
}
 
 
return MCAPI_TRUE;
}
 
 
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API: error checking routines //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME: mcapi_trans_channel_type OK
DESCRIPTION: Given an endpoint, returns the type of channel (if any)
associated with it.
PARAMETERS: endpoint: the endpoint to be checked
RETURN VALUE: the type of the channel (pkt,scalar or none)
***************************************************************************/
channel_type mcapi_trans_channel_type (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
//mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
rc = c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type;
/* unlock the database */
//mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_send_endpoint OK
DESCRIPTION:checks if the given endpoint is a send endpoint
PARAMETERS: endpoint: the endpoint to be checked
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_send_endpoint (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc = MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
if ((c_db->nodes[n].node_d.endpoints[e].connected) &&
(c_db->nodes[n].node_d.endpoints[e].recv_queue.recv_endpt == endpoint)) {
/* this endpoint has already been marked as a receive endpoint */
mcapi_dprintf(2," mcapi_trans_send_endpoint ERROR: this endpoint (%x) has already been connected as a receive endpoint\n",
endpoint);
rc = MCAPI_FALSE;
}
/* unlock the database */
//mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_recv_endpoint OK
DESCRIPTION:checks if the given endpoint can be or is already a receive endpoint
PARAMETERS: endpoint: the endpoint to be checked
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_recv_endpoint (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc = MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
//mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
if ((c_db->nodes[n].node_d.endpoints[e].connected) &&
(c_db->nodes[n].node_d.endpoints[e].recv_queue.send_endpt == endpoint)) {
/* this endpoint has already been marked as a send endpoint */
mcapi_dprintf(2," mcapi_trans_recv_endpoint ERROR: this endpoint (%x) has already been connected as a send endpoint\n",
endpoint);
rc = MCAPI_FALSE;
}
/* unlock the database */
//mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_port OK
DESCRIPTION:checks if the given port_num is a valid port_num for this system
PARAMETERS: port_num: the port num to be checked
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_port(mcapi_uint_t port_num)
{
return MCAPI_TRUE;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_node OK
DESCRIPTION: checks if the given node_num is a valid node_num for this system
PARAMETERS: node_num: the node num to be checked
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_node(mcapi_uint_t node_num)
{
return MCAPI_TRUE;
}
/***************************************************************************
NAME: mcapi_trans_valid_endpoint OK
DESCRIPTION: checks if the given endpoint handle refers to a valid endpoint
PARAMETERS: endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_endpoint (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (mcapi_trans_decode_handle_internal(endpoint,&n,&e)) {
rc = c_db->nodes[n].node_d.endpoints[e].valid;
}
 
mcapi_dprintf(3,"mcapi_trans_valid_endpoint endpoint=0x%lx (database indices: n=%d,e=%d) rc=%d\n",endpoint,n,e,rc);
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_endpoint_exists OK
DESCRIPTION: checks if an endpoint has been created for this port id
PARAMETERS: port id
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_endpoint_exists (uint32_t port_num)
{
uint32_t n,i,node_num;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
if (port_num == MCAPI_PORT_ANY) {
return rc;
}
 
/* lock the database */
//mcapi_trans_access_database_pre();
rv = mcapi_trans_get_node_num(&node_num);
//assert(rv);
n = mcapi_trans_get_node_index(node_num);
 
/* Note: we can't just iterate for i < num_endpoints because endpoints can
be deleted which would fragment the endpoints array. */
for (i = 0; i < MAX_ENDPOINTS; i++) {
if (c_db->nodes[n].node_d.endpoints[i].valid &&
c_db->nodes[n].node_d.endpoints[i].port_num == port_num) {
rc = MCAPI_TRUE;
break;
}
}
/* unlock the database */
//mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_valid_endpoints OK
DESCRIPTION: checks if the given endpoint handles refer to valid endpoints
PARAMETERS: endpoint1, endpoint2
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_endpoints (mcapi_endpoint_t endpoint1,
mcapi_endpoint_t endpoint2)
{
uint16_t n1,e1;
uint16_t n2,e2;
mcapi_boolean_t rc = MCAPI_FALSE;
/* lock the database */
//mcapi_trans_access_database_pre();
 
// decode_internal already tests for validity.
if (mcapi_trans_decode_handle_internal(endpoint1,&n1,&e1) &&
mcapi_trans_decode_handle_internal(endpoint2,&n2,&e2)) {
rc = MCAPI_TRUE;
}
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_pktchan_recv_isopen OK
DESCRIPTION:checks if the channel is open for a given handle
PARAMETERS: receive_handle
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_pktchan_recv_isopen (mcapi_pktchan_recv_hndl_t receive_handle)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(receive_handle,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].open);
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
 
/***************************************************************************
NAME:mcapi_trans_pktchan_send_isopen OK
DESCRIPTION:checks if the channel is open for a given handle
PARAMETERS: send_handle
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_pktchan_send_isopen (mcapi_pktchan_send_hndl_t send_handle)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
//mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(send_handle,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].open);
/* unlock the database */
//mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_sclchan_recv_isopen OK
DESCRIPTION:checks if the channel is open for a given handle
PARAMETERS: receive_handle
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_sclchan_recv_isopen (mcapi_sclchan_recv_hndl_t receive_handle)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
//mcapi_trans_access_database_pre();
rv = mcapi_trans_decode_handle_internal(receive_handle,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].open);
/* unlock the database */
//mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_sclchan_send_isopen OK
DESCRIPTION:checks if the channel is open for a given handle
PARAMETERS: send_handle
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_sclchan_send_isopen (mcapi_sclchan_send_hndl_t send_handle)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(send_handle,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].open);
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_endpoint_channel_isopen OK
DESCRIPTION:checks if a channel is open for a given endpoint
PARAMETERS: endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_endpoint_channel_isopen (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].open);
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_endpoint_isowner OK
DESCRIPTION:checks if the given endpoint is owned by the calling node
PARAMETERS: endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_endpoint_isowner (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
mcapi_uint_t node_num;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
rv = mcapi_trans_get_node_num(&node_num);
//assert(rv);
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
rc = ((c_db->nodes[n].node_d.endpoints[e].valid) &&
(c_db->nodes[n].node_num == node_num));
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_channel_connected OK
DESCRIPTION:checks if the given endpoint channel is connected
PARAMETERS: endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_channel_connected (mcapi_endpoint_t endpoint)
{
uint16_t n,e;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
rc = ((c_db->nodes[n].node_d.endpoints[e].valid) &&
(c_db->nodes[n].node_d.endpoints[e].connected));
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_compatible_endpoint_attributes OK
DESCRIPTION:checks if the given endpoints have compatible attributes
PARAMETERS: send_endpoint,recv_endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_compatible_endpoint_attributes (mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t recv_endpoint)
{
/* FIXME: (errata A3) currently un-implemented */
return MCAPI_TRUE;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_pktchan_send_handle Ok
DESCRIPTION:checks if the given pkt channel send handle is valid
PARAMETERS: handle
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_pktchan_send_handle( mcapi_pktchan_send_hndl_t handle)
{
uint16_t n,e;
channel_type type;
int rc = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
type =MCAPI_PKT_CHAN;
if (mcapi_trans_decode_handle_internal(handle,&n,&e)) {
if (c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type == type) {
rc = MCAPI_TRUE;
} else {
mcapi_dprintf(2," mcapi_trans_valid_pktchan_send_handle node=%d,port=%d returning false channel_type != MCAPI_PKT_CHAN\n",
c_db->nodes[n].node_num,c_db->nodes[n].node_d.endpoints[e].port_num);
}
}
rc = MCAPI_TRUE;
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_pktchan_recv_handle OK
DESCRIPTION:checks if the given pkt channel recv handle is valid
PARAMETERS: handle
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_pktchan_recv_handle( mcapi_pktchan_recv_hndl_t handle)
{
uint16_t n,e;
channel_type type;
int rc = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
type = MCAPI_PKT_CHAN;
if (mcapi_trans_decode_handle_internal(handle,&n,&e)) {
if (c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type == type) {
rc = MCAPI_TRUE;
} else {
mcapi_dprintf(2," mcapi_trans_valid_pktchan_recv_handle node=%d,port=%d returning false channel_type != MCAPI_PKT_CHAN\n",
c_db->nodes[n].node_num,c_db->nodes[n].node_d.endpoints[e].port_num);
}
}
rc = MCAPI_TRUE;
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_sclchan_send_handle OK
DESCRIPTION: checks if the given scalar channel send handle is valid
PARAMETERS: handle
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_sclchan_send_handle( mcapi_sclchan_send_hndl_t handle)
{
uint16_t n,e;
channel_type type;
int rc = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
type = MCAPI_SCL_CHAN;
if (mcapi_trans_decode_handle_internal(handle,&n,&e)) {
if (c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type == type) {
rc = MCAPI_TRUE;
} else {
mcapi_dprintf(2," mcapi_trans_valid_sclchan_send_handle node=%d,port=%d returning false channel_type != MCAPI_SCL_CHAN\n",
c_db->nodes[n].node_num,c_db->nodes[n].node_d.endpoints[e].port_num);
}
}
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_sclchan_recv_handle OK
DESCRIPTION:checks if the given scalar channel recv handle is valid
PARAMETERS:
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_sclchan_recv_handle( mcapi_sclchan_recv_hndl_t handle)
{
uint16_t n,e;
channel_type type;
 
int rc = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
type= MCAPI_SCL_CHAN;
if (mcapi_trans_decode_handle_internal(handle,&n,&e)) {
if (c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type == type) {
rc = MCAPI_TRUE;
} else {
mcapi_dprintf(2," mcapi_trans_valid_sclchan_recv_handle node=%d,port=%d returning false channel_type != MCAPI_SCL_CHAN\n",
c_db->nodes[n].node_num,c_db->nodes[n].node_d.endpoints[e].port_num);
}
}
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_initialized OK
DESCRIPTION: checks if the given node_id has called initialize
PARAMETERS: node_id
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_initialized (mcapi_node_t node_id)
{
//int i;
mcapi_boolean_t rc = MCAPI_FALSE;
 
/* if (mcapi_trans_initialize()) { */
/* /\* lock the database *\/ */
/* // mcapi_trans_access_database_pre_nocheck(); */
/* for (i = 0; i < MAX_NODES; i++) { */
/* if ((c_db->nodes[i].valid) && (c_db->nodes[i].node_num == node_id)) */
/* rc = MCAPI_TRUE; */
/* break; */
/* } */
 
/* /\* unlock the database *\/ */
/* // mcapi_trans_access_database_post_nocheck(); */
/* } */
 
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_num_endpoints OK
DESCRIPTION: returns the current number of endpoints for the calling node
PARAMETERS: none
RETURN VALUE: num_endpoints
***************************************************************************/
mcapi_uint32_t mcapi_trans_num_endpoints()
{
int rc = 0;
uint32_t node_num,node_index;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_get_node_num(&node_num);
//assert(rv);
 
node_index = mcapi_trans_get_node_index(node_num);
 
rc = c_db->nodes[node_index].node_d.num_endpoints;
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_valid_priority OK
DESCRIPTION:checks if the given priority level is valid
PARAMETERS: priority
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_valid_priority(mcapi_priority_t priority)
{
return ((priority >=0) && (priority <= MCAPI_MAX_PRIORITY));
}
 
/***************************************************************************
NAME:mcapi_trans_connected OK
DESCRIPTION: checks if the given endpoint is connected
PARAMETERS: endpoint
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_connected(mcapi_endpoint_t endpoint)
{
mcapi_boolean_t rc = MCAPI_FALSE;
uint16_t n,e;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
rc = (c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type != MCAPI_NO_CHAN);
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME:valid_status_param
DESCRIPTION: checks if the given status is a valid status parameter
PARAMETERS: status
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t valid_status_param (mcapi_status_t* mcapi_status)
{
return (mcapi_status != NULL);
}
 
/***************************************************************************
NAME:valid_version_param OK
DESCRIPTION: checks if the given version is a valid version parameter
PARAMETERS: version
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t valid_version_param (mcapi_version_t* mcapi_version)
{
return (mcapi_version != NULL);
}
 
 
/***************************************************************************
NAME:valid_buffer_param OK
DESCRIPTION:checks if the given buffer is a valid buffer parameter
PARAMETERS: buffer
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t valid_buffer_param (void* buffer)
{
return (buffer != NULL);
}
 
 
/***************************************************************************
NAME: valid_request_param OK
DESCRIPTION:checks if the given request is a valid request parameter
PARAMETERS: request
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t valid_request_param (mcapi_request_t* request)
{
return (request != NULL);
}
 
 
/***************************************************************************
NAME:valid_size_param OK
DESCRIPTION: checks if the given size is a valid size parameter
PARAMETERS: size
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t valid_size_param (size_t* size)
{
return (size != NULL);
}
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API: endpoints //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME:mcapi_trans_create_endpoint OK
DESCRIPTION: This function just looks up the node_num and calls
mcapi_trans_create_endpoint_. NOTE: the reason I separated create_endpoint
into these two functions is because it's useful for the testharness to be
able to explicitly create multiple nodes and multiple endpoints on those
nodes within the same process/thread. This is very useful for testing and
this decoupling allows that. See ./tests/valid_endpoint.c.
PARAMETERS:
ep - the endpoint to be filled in
port_num - the port id (only valid if !anonymous)
anonymous - whether or not this should be an anonymous endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_create_endpoint(mcapi_endpoint_t* ep, mcapi_uint_t port_num,
mcapi_boolean_t anonymous)
{
mcapi_uint_t node_num;
mcapi_boolean_t rv = MCAPI_FALSE;
rv = mcapi_trans_get_node_num(&node_num);
//assert (rv);
return mcapi_trans_create_endpoint_(ep,node_num,port_num,anonymous);
}
 
/***************************************************************************
NAME:mcapi_trans_create_endpoint_ OK
DESCRIPTION:create endpoint <node_num,port_num> and return it's handle
PARAMETERS:
ep - the endpoint to be filled in
port_num - the port id (only valid if !anonymous)
anonymous - whether or not this should be an anonymous endpoint
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_create_endpoint_(mcapi_endpoint_t* ep, mcapi_uint_t node_num, mcapi_uint_t port_num,
mcapi_boolean_t anonymous)
{
int i, node_index, endpoint_index;
mcapi_boolean_t rc = MCAPI_FALSE;
 
node_num = my_node_id;
/* lock the database */
// mcapi_trans_access_database_pre();
 
node_index = mcapi_trans_get_node_index (node_num);
 
/* make sure there's room - mcapi should have already checked this */
//assert (c_db->nodes[node_index].node_d.num_endpoints < MAX_ENDPOINTS);
/* create the endpoint */
/* find the first available endpoint index */
endpoint_index = MAX_ENDPOINTS;
for (i = 0; i < MAX_ENDPOINTS; i++) {
if (! c_db->nodes[node_index].node_d.endpoints[i].valid) {
endpoint_index = i;
break;
}
}
//assert(node_index < MAX_NODES);
//assert(endpoint_index < MAX_ENDPOINTS);
//assert (c_db->nodes[node_index].node_d.endpoints[endpoint_index].valid == MCAPI_FALSE);
/* initialize the endpoint entry */
c_db->nodes[node_index].node_d.endpoints[endpoint_index].valid = MCAPI_TRUE;
c_db->nodes[node_index].node_d.endpoints[endpoint_index].port_num = port_num;
c_db->nodes[node_index].node_d.endpoints[endpoint_index].open = MCAPI_FALSE;
c_db->nodes[node_index].node_d.endpoints[endpoint_index].anonymous = anonymous;
c_db->nodes[node_index].node_d.endpoints[endpoint_index].num_attributes = 0;
c_db->nodes[node_index].node_d.num_endpoints++;
/* set the handle */
//*ep = mcapi_trans_encode_handle_internal (node_index,endpoint_index);
*ep = node_num;
*ep = node_num << 16;
*ep = *ep | port_num;
//printf("my_ep=%x\n",*ep);
//dprintf(" mcapi_trans_create_endpoint (node_num=%x port_num=%d) ep=%x, node_index=%d, endpoint_index=%d\n",
// node_num,port_num,*ep,node_index,endpoint_index);
rc = MCAPI_TRUE;
/* unlock the database */
// mcapi_trans_access_database_post();
 
 
ioctl(fdevs[node_num],SET_HIBI_RX_ADDR,(void*) (hibiBaseAddresses[node_num] | port_num) );
ioctl(fdevs[node_num],SET_HIBI_RX_PACKETS,(void*) DEFAULT_MSG_SIZE);
ioctl(fdevs[node_num],SET_HIBI_RX_BLOCKING,(void*) HIBI_READ_BLOCKING_MODE);
 
return rc;
}
 
 
/***************************************************************************
NAME:mcapi_trans_get_endpoint_i
DESCRIPTION:non-blocking get endpoint for the given <node_num,port_num>
PARAMETERS:
endpoint - the endpoint handle to be filled in
node_num - the node id
port_num - the port id
request - the request handle to be filled in when the task is complete
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_get_endpoint_i( mcapi_endpoint_t* endpoint,mcapi_uint_t node_num,
mcapi_uint_t port_num, mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
mcapi_boolean_t valid = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_TRUE : MCAPI_FALSE;
mcapi_boolean_t completed = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (valid) {
/* try to get the endpoint */
if (mcapi_trans_get_endpoint_internal (endpoint,node_num,port_num)) {
completed = MCAPI_TRUE;
} else {
request->node_num = node_num;
request->port_num = port_num;
}
}
 
setup_request_internal(endpoint,request,mcapi_status,completed,0,NULL,GET_ENDPT);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
/***************************************************************************
NAME:mcapi_trans_get_endpoint_internal
DESCRIPTION:get endpoint for the given <node_num,port_num>
PARAMETERS:
endpoint - the endpoint handle to be filled in
node_num - the node id
port_num - the port id
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_get_endpoint_internal (mcapi_endpoint_t *e, mcapi_uint_t node_num,
mcapi_uint_t port_num)
{
int i,j;
int rc = MCAPI_FALSE;
/* the database should already be locked */
 
mcapi_dprintf(2," mcapi_trans_get_endpoint_internal node_num=%d, port_num=%d\n",
node_num,port_num);
for (i = 0; i < c_db->num_nodes; i++) {
if (c_db->nodes[i].node_num == node_num) {
for (j = 0; j < c_db->nodes[i].node_d.num_endpoints; j++) {
if ((c_db->nodes[i].node_d.endpoints[j].valid) &&
(c_db->nodes[i].node_d.endpoints[j].port_num == port_num)) {
/* return the handle */
*e = mcapi_trans_encode_handle_internal (i,j);
rc = MCAPI_TRUE;
}
}
}
}
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_get_endpoint
DESCRIPTION:blocking get endpoint for the given <node_num,port_num>
PARAMETERS:
endpoint - the endpoint handle to be filled in
node_num - the node id
port_num - the port id
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
void mcapi_trans_get_endpoint(mcapi_endpoint_t *e, mcapi_uint_t node_num,
mcapi_uint_t port_num)
{
*e = node_num;
*e = node_num << 16;
*e = *e | port_num;
 
/* lock the database */
// mcapi_trans_access_database_pre();
//while(!mcapi_trans_get_endpoint_internal (e,node_num,port_num)) {
/* yield */
//mcapi_dprintf(5," mcapi_trans_get_endpoint - attempting to yield\n");
//transport_sm_yield_internal();
//}
/* lock the database */
// mcapi_trans_access_database_post();
}
 
 
/***************************************************************************
NAME: mcapi_trans_delete_endpoint
DESCRIPTION:delete the given endpoint
PARAMETERS: endpoint
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_delete_endpoint( mcapi_endpoint_t endpoint)
{
uint16_t n,e;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(endpoint,&n,&e);
//assert(rv);
mcapi_dprintf(2," mcapi_trans_delete_endpoint_internal node_num=%d, port_num=%d\n",
c_db->nodes[n].node_num,c_db->nodes[n].node_d.endpoints[e].port_num);
 
/* remove the endpoint */
c_db->nodes[n].node_d.num_endpoints--;
/* zero out the old endpoint entry in the shared memory database */
memset (&c_db->nodes[n].node_d.endpoints[e],0,sizeof(endpoint_entry));
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API: messages //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME: mcapi_trans_msg_send OK
DESCRIPTION: sends a connectionless message from one endpoint to another (blocking)
PARAMETERS:
send_endpoint - the sending endpoint's handle
receive_endpoint - the receiving endpoint's handle
buffer - the user supplied buffer
buffer_size - the size in bytes of the buffer
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_msg_send( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint, char* buffer,
size_t buffer_size)
{
mcapi_request_t request;
mcapi_status_t status = MCAPI_SUCCESS;
size_t size;
 
/* use non-blocking followed by wait */
mcapi_trans_msg_send_i (send_endpoint,receive_endpoint,buffer,buffer_size,&request,&status);
mcapi_trans_wait (&request,&size,&status,MCAPI_INFINITE);
 
if (status == MCAPI_SUCCESS) {
return MCAPI_TRUE;
}
return MCAPI_FALSE;
}
 
/***************************************************************************
NAME: mcapi_trans_msg_send_i
DESCRIPTION: sends a connectionless message from one endpoint to another (non-blocking)
PARAMETERS:
send_endpoint - the sending endpoint's handle
receive_endpoint - the receiving endpoint's handle
buffer - the user supplied buffer
buffer_size - the size in bytes of the buffer
request - the request handle to be filled in when the task is complete
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_msg_send_i( mcapi_endpoint_t send_endpoint, mcapi_endpoint_t receive_endpoint,
char* buffer, size_t buffer_size, mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
int port_id,node_id = 0;
uint16_t sn,se;
uint16_t rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
mcapi_dprintf(2," mcapi_trans_msg_send_i se=%x re=%x\n",send_endpoint,receive_endpoint);
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
completed = MCAPI_TRUE; /* sends complete immediately */
/* these function calls were in asserts */
rv = mcapi_trans_decode_handle_internal(send_endpoint,&sn,&se);
//assert(rv);
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
/* FIXME: (errata B1) is it really an error to send/recv a message with a _connected_ endpoint? */
//assert (c_db->nodes[sn].node_d.endpoints[se].recv_queue.channel_type == MCAPI_NO_CHAN);
//assert (c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_NO_CHAN);
printf("TRANS: Sending message...\n");
// TODO: FILE_DEVICE send_data
port_id = receive_endpoint & 0x0000FFFF;
node_id = receive_endpoint >> 16;
 
if(port_id != 0)
{
lseek(fdevs[node_id], port_id, SEEK_SET);
}
write(fdevs[node_id], buffer , buffer_size);
//if (!mcapi_trans_send_internal (sn,se,rn,re,buffer,buffer_size,MCAPI_FALSE,0)) {
/* assume couldn't get a buffer */
// *mcapi_status = MCAPI_ENO_BUFFER;
//}
}
//setup_request_internal(&receive_endpoint,request,mcapi_status,completed,buffer_size,NULL,SEND);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_msg_recv
DESCRIPTION:receives a message from this endpoints receive queue (blocking)
PARAMETERS:
receive_endpoint - the receiving endpoint
buffer - the user supplied buffer to copy the message into
buffer_size - the size of the user supplied buffer
received_size - the actual size of the message received
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_msg_recv( mcapi_endpoint_t receive_endpoint, char* buffer,
size_t buffer_size, size_t* received_size)
{
mcapi_request_t request;
mcapi_status_t status = MCAPI_SUCCESS;
 
mcapi_dprintf(2," mcapi_trans_msg_recv re=%x\n",receive_endpoint);
 
/* use non-blocking followed by wait */
mcapi_trans_msg_recv_i (receive_endpoint,buffer,buffer_size,&request,&status);
// TODO: this wait never finishes on TTA. WHY???
// mcapi_trans_wait (&request,received_size,&status,MCAPI_INFINITE);
 
if (status == MCAPI_SUCCESS) {
return MCAPI_TRUE;
}
return MCAPI_FALSE;
 
}
 
/***************************************************************************
NAME:mcapi_trans_msg_recv_i
DESCRIPTION:receives a message from this endpoints receive queue (non-blocking)
PARAMETERS:
receive_endpoint - the receiving endpoint
buffer - the user supplied buffer to copy the message into
buffer_size - the size of the user supplied buffer
received_size - the actual size of the message received
request - the request to be filled in when the task is completed.
RETURN VALUE:MCAPI_TRUE/MCAPI_FALSE indicating success or failure
***************************************************************************/
void mcapi_trans_msg_recv_i( mcapi_endpoint_t receive_endpoint, char* buffer,
size_t buffer_size, mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
 
uint16_t rn,re,rp;
//size_t received_size = 0;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
mcapi_dprintf(2," mcapi_trans_msg_recv_i re=%x\n",receive_endpoint);
if (!completed) {
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
/* FIXME: (errata B1) is it really an error recv a message with a _connected_ endpoint? */
//assert (c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_NO_CHAN);
 
//if (mcapi_trans_recv_internal(rn,re,(void*)&buffer,buffer_size,&received_size,MCAPI_FALSE,NULL)) {
// completed = MCAPI_TRUE;
// buffer_size = received_size;
//}
}
rn = receive_endpoint & 0x0000FFFF;
rp = receive_endpoint >> 16;
 
ioctl(fdevs[rn],SET_HIBI_RX_ADDR,(void*) (hibiBaseAddresses[rn] | rp));
ioctl(fdevs[rn],SET_HIBI_RX_PACKETS,(void*) DEFAULT_MSG_SIZE);
ioctl(fdevs[rn],SET_HIBI_RX_BLOCKING,(void*) HIBI_READ_BLOCKING_MODE);
 
// TODO: FILE_DEV get received data from hibi_pe_dma
read(fdevs[0], (char*) &buffer, buffer_size);
// initialize msg channel
//initCh(hibi_address_table[my_node_id] + receive_endpoint & 0x0000FFFF, receive_endpoint & 0x0000FFFF, (int)(rx_data), buffer_size);
 
setup_request_internal(&receive_endpoint,request,mcapi_status,completed,buffer_size,(void**)((void*)&buffer),RECV);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME: mcapi_trans_msg_available
DESCRIPTION: counts the number of messages in the endpoints receive queue
PARAMETERS: endpoint
RETURN VALUE: the number of messages in the queue
***************************************************************************/
mcapi_uint_t mcapi_trans_msg_available( mcapi_endpoint_t receive_endpoint)
{
uint16_t rn,re;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
 
 
//rc = c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements;
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API: packet channels //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME:mcapi_trans_connect_pktchan_i
DESCRIPTION: connects a packet channel
PARAMETERS:
send_endpoint - the sending endpoint handle
receive_endpoint - the receiving endpoint handle
request - the request to be filled in when the task is complete
mcapi_status -
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_connect_pktchan_i( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (!completed) {
mcapi_trans_connect_channel_internal (send_endpoint,receive_endpoint,MCAPI_PKT_CHAN);
completed = MCAPI_TRUE;
}
setup_request_internal(&receive_endpoint,request,mcapi_status,completed,0,NULL,0);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
/***************************************************************************
NAME: mcapi_trans_open_pktchan_recv_i
DESCRIPTION: opens the receive endpoint on a packet channel
PARAMETERS:
recv_handle - the receive channel handle to be filled in
receive_endpoint - the receiving endpoint handle
request - the request to be filled in when the task is complete
mcapi_status
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_open_pktchan_recv_i( mcapi_pktchan_recv_hndl_t* recv_handle,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
//initCh(hibi_address_table[my_node_id]+(receive_endpoint & 0x0000FFFF) , receive_endpoint & 0x0000FFFF, (int)(rx_data), 1);
uint16_t rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
completed = MCAPI_TRUE;
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
mcapi_trans_open_channel_internal (rn,re);
/* fill in the channel handle */
*recv_handle = mcapi_trans_encode_handle_internal(rn,re);
/* has the channel been connected yet? */
if ( c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_PKT_CHAN) {
completed = MCAPI_TRUE;
}
mcapi_dprintf(2," mcapi_trans_open_pktchan_recv_i (node_num=%d,port_num=%d) handle=%x\n",
c_db->nodes[rn].node_num,c_db->nodes[rn].node_d.endpoints[re].port_num,*recv_handle);
}
 
//setup_request_internal(&receive_endpoint,request,mcapi_status,completed,0,NULL,OPEN_PKTCHAN);
/* unlock the database */
// mcapi_trans_access_database_post();
*mcapi_status = MCAPI_SUCCESS;
}
 
 
/***************************************************************************
NAME: mcapi_trans_open_pktchan_send_i
DESCRIPTION: opens the send endpoint on a packet channel
PARAMETERS:
send_handle - the send channel handle to be filled in
receive_endpoint - the receiving endpoint handle
request - the request to be filled in when the task is complete
mcapi_status
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_open_pktchan_send_i( mcapi_pktchan_send_hndl_t* send_handle,
mcapi_endpoint_t send_endpoint,mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
uint16_t sn,se;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(send_endpoint,&sn,&se);
//assert(rv);
/* mark the endpoint as open */
c_db->nodes[sn].node_d.endpoints[se].open = MCAPI_TRUE;
/* fill in the channel handle */
*send_handle = mcapi_trans_encode_handle_internal(sn,se);
 
/* has the channel been connected yet? */
if ( c_db->nodes[sn].node_d.endpoints[se].recv_queue.channel_type == MCAPI_PKT_CHAN) {
completed = MCAPI_TRUE;
}
mcapi_dprintf(2," mcapi_trans_open_pktchan_send_i (node_num=%d,port_num=%d) handle=%x\n",
c_db->nodes[sn].node_num,c_db->nodes[sn].node_d.endpoints[se].port_num,*send_handle);
}
 
setup_request_internal(&send_endpoint,request,mcapi_status,completed,0,NULL,OPEN_PKTCHAN);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_pktchan_send_i
DESCRIPTION: sends a packet on a packet channel (non-blocking)
PARAMETERS:
send_handle - the send channel handle
buffer - the buffer
size - the size in bytes of the buffer
request - the request handle to be filled in when the task is complete
mcapi_status -
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_pktchan_send_i( mcapi_pktchan_send_hndl_t send_handle,
void* buffer, size_t size, mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
uint16_t sn,se,rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
mcapi_dprintf(2," mcapi_trans_pktchan_send_i send_handle=%x\n",send_handle);
 
/* lock the database */
// mcapi_trans_access_database_pre();
completed = MCAPI_FALSE;
 
if (!completed) {
rv = mcapi_trans_decode_handle_internal(send_handle,&sn,&se);
//assert(rv);
rv = mcapi_trans_decode_handle_internal(c_db->nodes[sn].node_d.endpoints[se].recv_queue.recv_endpt,&rn,&re);
//assert(rv);
/* if (!mcapi_trans_send_internal (sn,se,rn,re,(char*)buffer,size,MCAPI_FALSE,0)) { */
/* *mcapi_status = MCAPI_ENO_BUFFER; */
/* } */
 
write(fdevs[0], buffer , size);
 
 
completed = MCAPI_TRUE;
}
 
setup_request_internal(&send_handle,request,mcapi_status,completed,size,NULL,SEND);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_pktchan_send
DESCRIPTION: sends a packet on a packet channel (blocking)
PARAMETERS:
send_handle - the send channel handle
buffer - the buffer
size - the size in bytes of the buffer
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_pktchan_send( mcapi_pktchan_send_hndl_t send_handle,
void* buffer, size_t size)
{
mcapi_request_t request;
mcapi_status_t status = MCAPI_SUCCESS;
 
mcapi_dprintf(2," mcapi_trans_pktchan_send re=%x\n",send_handle);
 
/* use non-blocking followed by wait */
mcapi_trans_pktchan_send_i (send_handle,buffer,size,&request,&status);
mcapi_trans_wait (&request,&size,&status,MCAPI_INFINITE);
status = MCAPI_SUCCESS;
if (status == MCAPI_SUCCESS) {
return MCAPI_TRUE;
}
return MCAPI_FALSE;
}
 
 
/***************************************************************************
NAME:mcapi_trans_pktchan_recv_i
DESCRIPTION: receives a packet on a packet channel (non-blocking)
PARAMETERS:
receive_handle - the send channel handle
buffer - a pointer to a pointer to a buffer
request - the request handle to be filled in when the task is complete
mcapi_status -
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_pktchan_recv_i( mcapi_pktchan_recv_hndl_t receive_handle,
void** buffer, mcapi_request_t* request,
mcapi_status_t* mcapi_status)
{
uint16_t rn,re,rp;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
size_t size = MAX_PKT_SIZE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
completed = MCAPI_FALSE;
if (!completed) {
rv = mcapi_trans_decode_handle_internal(receive_handle,&rn,&re);
//assert(rv);
/* *buffer will be filled in the with a ptr to an mcapi buffer */
//*buffer = NULL;
//*buffer = rx_data;
//decode handle
 
ioctl(fdevs[rn],SET_HIBI_RX_ADDR,(void*) (hibiBaseAddresses[rn] | rp) );
ioctl(fdevs[rn],SET_HIBI_RX_PACKETS,(void*) DEFAULT_MSG_SIZE);
ioctl(fdevs[rn],SET_HIBI_RX_BLOCKING,(void*) HIBI_READ_BLOCKING_MODE);
 
 
// TODO: FILE_DEV
read(fdevs[0], (char*) &buffer, 1);
 
//if (mcapi_trans_recv_internal (rn,re,buffer,MAX_PKT_SIZE,&size,MCAPI_FALSE,NULL)) {
completed = MCAPI_TRUE;
//}
}
 
setup_request_internal(&receive_handle,request,mcapi_status,completed,size,buffer,RECV);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_pktchan_recv
DESCRIPTION: receives a packet on a packet channel (blocking)
PARAMETERS:
send_handle - the send channel handle
buffer - the buffer
received_size - the size in bytes of the buffer
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE (only returns MCAPI_FALSE if it couldn't get a buffer)
***************************************************************************/
mcapi_boolean_t mcapi_trans_pktchan_recv( mcapi_pktchan_recv_hndl_t receive_handle,
void** buffer, size_t* received_size)
{
mcapi_request_t request;
mcapi_status_t status = MCAPI_SUCCESS;
 
mcapi_dprintf(2," mcapi_trans_pktchan_recv re=%x\n",receive_handle);
 
/* use non-blocking followed by wait */
mcapi_trans_pktchan_recv_i (receive_handle,buffer,&request,&status);
mcapi_trans_wait (&request,received_size,&status,MCAPI_INFINITE);
status = MCAPI_SUCCESS;
if (status == MCAPI_SUCCESS) {
return MCAPI_TRUE;
}
return MCAPI_FALSE;
}
 
/***************************************************************************
NAME: mcapi_trans_pktchan_available
DESCRIPTION: counts the number of elements in the endpoint receive queue
identified by the receive handle.
PARAMETERS: receive_handle - the receive channel handle
RETURN VALUE: the number of elements in the receive queue
***************************************************************************/
mcapi_uint_t mcapi_trans_pktchan_available( mcapi_pktchan_recv_hndl_t receive_handle)
{
uint16_t rn,re;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(receive_handle,&rn,&re);
//assert(rv);
rc = c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements;
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_pktchan_free
DESCRIPTION: frees the given buffer
PARAMETERS: buffer pointer
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE indicating success or failure (buffer not found)
***************************************************************************/
mcapi_boolean_t mcapi_trans_pktchan_free( void* buffer)
{
int rc = MCAPI_TRUE;
buffer_entry* b_e;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
/* optimization - just do pointer arithmetic on the buffer pointer to get
the base address of the buffer_entry structure. */
b_e = buffer-9;
if (b_e->magic_num == MAGIC_NUM) {
memset(b_e,0,sizeof(buffer_entry));
} else {
/* didn't find the buffer */
rc = MCAPI_FALSE;
}
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
 
/***************************************************************************
NAME:mcapi_trans_pktchan_recv_close_i
DESCRIPTION: non-blocking close of the receiving end of the packet channel
PARAMETERS: receive_handle
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_pktchan_recv_close_i( mcapi_pktchan_recv_hndl_t receive_handle,
mcapi_request_t* request, mcapi_status_t* mcapi_status)
{
uint16_t rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (!completed) {
rv = mcapi_trans_decode_handle_internal(receive_handle,&rn,&re);
//assert(rv);
mcapi_trans_close_channel_internal (rn,re);
completed = MCAPI_TRUE;
}
setup_request_internal(&receive_handle,request,mcapi_status,completed,0,NULL,0);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
 
/***************************************************************************
NAME:mcapi_trans_pktchan_send_close_i
DESCRIPTION: non-blocking close of the sending end of the packet channel
PARAMETERS: receive_handle
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_pktchan_send_close_i( mcapi_pktchan_send_hndl_t send_handle,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
uint16_t sn,se;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(send_handle,&sn,&se);
//assert(rv);
mcapi_trans_close_channel_internal (sn,se);
completed = MCAPI_TRUE;
}
setup_request_internal(&send_handle,request,mcapi_status,completed,0,NULL,0);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
//////////////////////////////////////////////////////////////////////////////
// //
// mcapi_trans API: scalar channels //
// //
//////////////////////////////////////////////////////////////////////////////
 
/***************************************************************************
NAME:mcapi_trans_connect_sclchan_i
DESCRIPTION: connects a scalar channel between the given two endpoints
PARAMETERS:
send_endpoint - the sending endpoint
receive_endpoint - the receiving endpoint
request - the request
mcapi_status - the status
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_connect_sclchan_i( mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (!completed) {
mcapi_trans_connect_channel_internal (send_endpoint,receive_endpoint,MCAPI_SCL_CHAN);
completed = MCAPI_TRUE;
}
setup_request_internal(&receive_endpoint,request,mcapi_status,completed,0,NULL,0);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME: mcapi_trans_open_sclchan_recv_i
DESCRIPTION: opens the receive endpoint on a packet channel
PARAMETERS:
recv_handle - the receive channel handle to be filled in
receive_endpoint - the receiving endpoint handle
request - the request to be filled in when the task is complete
mcapi_status
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_open_sclchan_recv_i( mcapi_sclchan_recv_hndl_t* recv_handle,
mcapi_endpoint_t receive_endpoint,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
uint16_t rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
mcapi_trans_open_channel_internal (rn,re);
/* fill in the channel handle */
*recv_handle = mcapi_trans_encode_handle_internal(rn,re);
/* has the channel been connected yet? */
if ( c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_SCL_CHAN){
completed = MCAPI_TRUE;
}
mcapi_dprintf(2," mcapi_trans_open_sclchan_recv_i (node_num=%d,port_num=%d) handle=%x\n",
c_db->nodes[rn].node_num,c_db->nodes[rn].node_d.endpoints[re].port_num,*recv_handle);
}
 
setup_request_internal(&receive_endpoint,request,mcapi_status,completed,0,NULL,OPEN_SCLCHAN);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
 
/***************************************************************************
NAME: mcapi_trans_open_sclchan_send_i
DESCRIPTION: opens the receive endpoint on a packet channel
PARAMETERS:
send_handle - the receive channel handle to be filled in
receive_endpoint - the receiving endpoint handle
request - the request to be filled in when the task is complete
mcapi_status
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_open_sclchan_send_i( mcapi_sclchan_send_hndl_t* send_handle,
mcapi_endpoint_t send_endpoint,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
uint16_t sn,se;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(send_endpoint,&sn,&se);
//assert(rv);
/* mark the endpoint as open */
c_db->nodes[sn].node_d.endpoints[se].open = MCAPI_TRUE;
 
/* fill in the channel handle */
*send_handle = mcapi_trans_encode_handle_internal(sn,se);
 
/* has the channel been connected yet? */
if ( c_db->nodes[sn].node_d.endpoints[se].recv_queue.channel_type == MCAPI_SCL_CHAN){
completed = MCAPI_TRUE;
}
mcapi_dprintf(2," mcapi_trans_open_sclchan_send_i (node_num=%d,port_num=%d) handle=%x\n",
c_db->nodes[sn].node_num,c_db->nodes[sn].node_d.endpoints[se].port_num,*send_handle);
}
 
setup_request_internal(&send_endpoint,request,mcapi_status,completed,0,NULL,OPEN_SCLCHAN);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_sclchan_send
DESCRIPTION: sends a packet on a packet channel (blocking)
PARAMETERS:
send_handle - the send channel handle
buffer - the buffer
size - the size in bytes of the buffer
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE
***************************************************************************/
mcapi_boolean_t mcapi_trans_sclchan_send(
mcapi_sclchan_send_hndl_t send_handle, uint64_t dataword, uint32_t size)
{
uint16_t sn,se,rn,re;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
mcapi_dprintf(2," mcapi_trans_sclchan_send send_handle=%x\n",send_handle);
/* lock the database */
// mcapi_trans_access_database_pre();
rv = mcapi_trans_decode_handle_internal(send_handle,&sn,&se);
//assert(rv);
rv = mcapi_trans_decode_handle_internal(c_db->nodes[sn].node_d.endpoints[se].recv_queue.recv_endpt,&rn,&re);
//assert(rv);
rc = mcapi_trans_send_internal (sn,se,rn,re,NULL,size,MCAPI_TRUE,dataword);
 
write(fdevs[0], &dataword , size);
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
 
/***************************************************************************
NAME:mcapi_trans_sclchan_recv
DESCRIPTION: receives a packet on a packet channel (blocking)
PARAMETERS:
send_handle - the send channel handle
buffer - the buffer
received_size - the size in bytes of the buffer
RETURN VALUE: MCAPI_TRUE/MCAPI_FALSE (only returns MCAPI_FALSE if it couldn't get a buffer)
***************************************************************************/
mcapi_boolean_t mcapi_trans_sclchan_recv(
mcapi_sclchan_recv_hndl_t receive_handle, uint64_t *data,uint32_t size)
{
uint16_t rn,re;
size_t received_size;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
rv = mcapi_trans_decode_handle_internal(receive_handle,&rn,&re);
//assert(rv);
if (mcapi_trans_recv_internal (rn,re,NULL,size,&received_size,MCAPI_TRUE,data) &&
received_size == size) {
rc = MCAPI_TRUE;
}
 
/* FIXME: (errata A2) if size != received_size then we shouldn't remove the item from the
endpoints receive queue */
/* unlock the database */
// mcapi_trans_access_database_post();
return rc;
}
 
/***************************************************************************
NAME: mcapi_trans_sclchan_available
DESCRIPTION: counts the number of elements in the endpoint receive queue
identified by the receive handle.
PARAMETERS: receive_handle - the receive channel handle
RETURN VALUE: the number of elements in the receive queue
***************************************************************************/
mcapi_uint_t mcapi_trans_sclchan_available_i( mcapi_sclchan_recv_hndl_t receive_handle)
{
uint16_t rn,re;
int rc = MCAPI_FALSE;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(receive_handle,&rn,&re);
//assert(rv);
rc = c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements;
 
 
/* unlock the database */
// mcapi_trans_access_database_post();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_sclchan_recv_close_i
DESCRIPTION: non-blocking close of the receiving end of the scalar channel
PARAMETERS:
receive_handle -
request -
mcapi_status -
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_sclchan_recv_close_i( mcapi_sclchan_recv_hndl_t recv_handle,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
uint16_t rn,re;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(recv_handle,&rn,&re);
//assert(rv);
mcapi_trans_close_channel_internal (rn,re);
completed = MCAPI_TRUE;
}
setup_request_internal(&recv_handle,request,mcapi_status,completed,0,NULL,0);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
 
/***************************************************************************
NAME:mcapi_trans_sclchan_send_close_i
DESCRIPTION: non-blocking close of the sending end of the scalar channel
PARAMETERS:
send_handle -
request -
mcapi_status -
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_sclchan_send_close_i( mcapi_sclchan_send_hndl_t send_handle,
mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
uint16_t sn,se;
/* if errors were found at the mcapi layer, then the request is considered complete */
mcapi_boolean_t completed = (*mcapi_status == MCAPI_SUCCESS) ? MCAPI_FALSE : MCAPI_TRUE;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
if (!completed) {
rv = mcapi_trans_decode_handle_internal(send_handle,&sn,&se);
//assert(rv);
mcapi_trans_close_channel_internal (sn,se);
completed = MCAPI_TRUE;
}
setup_request_internal(&send_handle,request,mcapi_status,completed,0,NULL,0);
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
 
 
//////////////////////////////////////////////////////////////////////////////
// //
// test and wait functions //
// //
//////////////////////////////////////////////////////////////////////////////
 
/***************************************************************************
NAME:mcapi_trans_test_i
DESCRIPTION: Tests if the request has completed yet (non-blocking).
PARAMETERS:
request -
size -
mcapi_status -
RETURN VALUE: TRUE/FALSE indicating if the request has completed.
***************************************************************************/
mcapi_boolean_t mcapi_trans_test_i( mcapi_request_t* request, size_t* size,
mcapi_status_t* mcapi_status)
{
 
/* FIXME: (errata B6) need to be able to set EREQ_CANCELED just like wait does */
mcapi_boolean_t rc;
rc = MCAPI_FALSE;
mcapi_dprintf(3,"mcapi_trans_test_i request:0x%lx\n",(long unsigned int) request);
if (request->valid == MCAPI_FALSE) {
*mcapi_status = MCAPI_ENOTREQ_HANDLE;
rc = MCAPI_FALSE;
} else if (request->cancelled) {
*mcapi_status = MCAPI_EREQ_CANCELED;
rc = MCAPI_FALSE;
} else if (!(request->completed)) {
/* try to complete the request */
/* receives to an empty channel or get_endpt for an endpt that
doesn't yet exist are the only two types of non-blocking functions
that don't complete immediately for this implementation */
switch (request->type) {
case (RECV) :
check_receive_request (request); break;
case (GET_ENDPT) :
check_get_endpt_request (request);break;
default:
//assert(0);
break;
};
}
 
if (request->completed) {
*size = request->size;
*mcapi_status = request->status;
rc = MCAPI_TRUE;
}
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_wait
DESCRIPTION:Tests if the request has completed yet (non-blocking).
PARAMETERS:
send_handle -
request -
mcapi_status -
RETURN VALUE: TRUE indicating the request has completed or FALSE
indicating the request has been cancelled.
***************************************************************************/
mcapi_boolean_t mcapi_trans_wait( mcapi_request_t* request, size_t* size,
mcapi_status_t* mcapi_status,
mcapi_timeout_t timeout)
{
mcapi_timeout_t time = 0;
mcapi_boolean_t rc;
while(1) {
time++;
rc = mcapi_trans_test_i(request,size,mcapi_status);
if (request->completed) {
return rc;
}
/* yield */
mcapi_dprintf(5," mcapi_trans_wait - attempting to yield\n");
/* we don't have the lock, it's safe to just yield */
//sched_yield();
if ((timeout != MCAPI_INFINITE) && (time >= timeout)) {
*mcapi_status = MCAPI_EREQ_TIMEOUT;
return MCAPI_FALSE;
}
}
}
 
/***************************************************************************
NAME:mcapi_trans_wait_any
DESCRIPTION:Tests if any of the requests have completed yet (blocking).
Note: the request is now cleared if it has been completed or cancelled.
PARAMETERS:
send_handle -
request -
mcapi_status -
RETURN VALUE: TRUE indicating one of the requests has completed or FALSE
indicating one of the requests has been cancelled.
***************************************************************************/
mcapi_boolean_t mcapi_trans_wait_any(size_t number, mcapi_request_t** requests, size_t* size,
mcapi_status_t* mcapi_status,
mcapi_timeout_t timeout)
{
mcapi_timeout_t time = 0;
mcapi_boolean_t rc;
unsigned int i;
while(1) {
time++;
for (i = 0; i < number; i++) {
rc = mcapi_trans_test_i(requests[i],size,mcapi_status);
if (requests[i]->completed) {
return rc;
}
/* yield */
mcapi_dprintf(5," mcapi_trans_wait_any - attempting to yield\n");
/* we don't have the lock, it's safe to just yield */
//sched_yield();
if ((timeout != MCAPI_INFINITE) && (time >= timeout)) {
*mcapi_status = MCAPI_EREQ_TIMEOUT;
return MCAPI_FALSE;
}
}
}
}
 
/***************************************************************************
NAME:mcapi_trans_cancel
DESCRIPTION: Cancels the given request
PARAMETERS:
request -
mcapi_status -
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_cancel(mcapi_request_t* request,mcapi_status_t* mcapi_status)
{
if (request->valid == MCAPI_FALSE) {
*mcapi_status = MCAPI_ENOTREQ_HANDLE;
return;
} else if (request->cancelled) {
/* this reqeust has already been cancelled */
mcapi_dprintf(1," mcapi_trans_cancel - request was already cancelled\n");
*mcapi_status = MCAPI_EREQ_CANCELED;
return;
} else if (!(request->completed)) {
/* cancel the request */
request->cancelled = MCAPI_TRUE;
switch (request->type) {
case (RECV) :
cancel_receive_request (request); break;
case (GET_ENDPT) :
break;
default:
//assert(0);
break;
};
} else {
/* it's too late, the request has already completed */
mcapi_dprintf(1," mcapi_trans_cancel - request has already completed\n");
}
}
 
 
//////////////////////////////////////////////////////////////////////////////
// //
// misc helper functions //
// //
//////////////////////////////////////////////////////////////////////////////
 
/***************************************************************************
NAME:mcapi_trans_signal_handler
DESCRIPTION: The purpose of this function is to catch signals so that we
can clean up our shared memory and sempaphore resources cleanly.
PARAMETERS: the signal
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_signal_handler ( int sig )
{
/* /\* Since this handler is established for more than one kind of signal, */
/* it might still get invoked recursively by delivery of some other kind */
/* of signal. Use a static variable to keep track of tha *\/ */
/* if (fatal_error_in_progress) */
/* raise (sig); */
/* fatal_error_in_progress = 1; */
/* /\* clean up ipc resources *\/ */
/* fprintf(stderr,"FAIL: received signal, freeing semaphore and shared memory\n"); */
/* mcapi_trans_finalize(); */
/* /\* Now reraise the signal. We reactivate the signal's */
/* default handling, which is to terminate the process. */
/* We could just call exit or abort, */
/* but reraising the signal sets the return status */
/* from the process correctly. *\/ */
/* signal (sig, SIG_DFL); */
/* raise (sig); */
}
 
/***************************************************************************
NAME: print_tid
DESCRIPTION: Displays the thread id.
PARAMETERS: t - opaque pthread_t handle
RETURN VALUE: string representing the TID value
***************************************************************************/
//const char *print_tid(pthread_t t) {
// static char buffer[100];
// char *p = buffer;
//
//#ifdef __linux
// /* We know that pthread_t is an unsigned long */
// sprintf(p, "%lu", t);
//#else
// /* Just print out the contents of the pthread_t */ {
// char *const tend = (char *) ((&t)+1);
// char *tp = (char *) &t;
// while (tp < tend) {
// p += sprintf (p, "%02x", *tp);
// tp++;
// if (tp < tend)
// *p++ = ':';
// }
// }
//#endif
// return buffer;
//}
 
/***************************************************************************
NAME: mcapi_trans_set_debug_level
DESCRIPTION: Sets the debug level which controls verbosity.
PARAMETERS: d - the desired level
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_set_debug_level (int d)
{
//if (!WITH_DEBUG) {
//printf("ERROR mcapi_trans_set_debug_level : This library was built without debug support.\n");
//printf("If you want to enable debugging, re-build with the --enable-debug option.\n");
//} else {
mcapi_debug = d;
//}
}
 
/***************************************************************************
NAME: get_private_data_index
DESCRIPTION: Retuns the index for this <pid,tid> into the private globals array.
PARAMETERS: none
RETURN VALUE: The index.
***************************************************************************/
int get_private_data_index () {
/* { */
/* /\* note: an optimization to searching this structure would be for */
/* mcapi_initialize to return a handle that we could just use to */
/* index. *\/ */
/* int i; */
/* int pid; */
/* pthread_t tid; */
/* pid = getpid(); */
/* tid = pthread_self(); */
/* //assert(pid); */
/* for (i = 0; i < MAX_ENDPOINTS; i++) { */
/* if ((d[i].pid == pid) && (pthread_equal(d[i].tid,tid))) { */
/* return i; */
/* } */
/* if (d[i].pid == 0) { */
/* break; */
/* } */
/* } */
/* fprintf(stderr,"FAIL: PID:%u TID:%s (has initialize been called yet?)\n",pid,print_tid(tid)); */
return 0;
}
 
/***************************************************************************
NAME: setup_request_internal
DESCRIPTION: Sets up the request for a non-blocking function.
PARAMETERS:
handle -
request -
mcapi_status -
completed - whether the request has already been completed or not (usually
it has - receives to an empty queue or get_endpoint for endpoints that
don't yet exist are the two main cases where completed will be false)
size -
buffer - the buffer
type - the type of the request
RETURN VALUE:
***************************************************************************/
void setup_request_internal (mcapi_endpoint_t* handle,mcapi_request_t* request,
mcapi_status_t* mcapi_status, mcapi_boolean_t completed,
size_t size,void** buffer,mcapi_request_type type)
{
 
int i,qindex;
uint16_t n,e;
mcapi_boolean_t rv = MCAPI_FALSE;
 
if (!valid_request_param (request)) {
return;
}
 
/* the database should already be locked */
request->valid = MCAPI_TRUE;
request->status = *mcapi_status;
request->size = size;
request->cancelled = MCAPI_FALSE;
request->completed = completed;
/* this is hacky, there's probably a better way to do this */
if ((buffer != NULL) && (!completed)) {
rv = mcapi_trans_decode_handle_internal(*handle,&n,&e);
//assert(rv);
if ( c_db->nodes[n].node_d.endpoints[e].recv_queue.channel_type == MCAPI_PKT_CHAN) {
/* packet buffer means system buffer, so save the users pointer to the buffer */
request->buffer_ptr = buffer;
} else {
/* message buffer means user buffer, so save the users buffer */
request->buffer = *buffer;
}
}
request->type = type;
request->handle = *handle;
 
/* save the pointer so that we can fill it in (the endpoint may not have been created yet)
an alternative is to make buffer a void* and use it for everything (messages, endpoints, etc.) */
if (request->type == GET_ENDPT) {
request->endpoint = handle;
}
 
/* if this was a non-blocking receive to an empty queue, then reserve the next buffer */
if ((type == RECV) && (!completed)) {
rv = mcapi_trans_decode_handle_internal(*handle,&n,&e);
//assert(rv);
/*find the queue entry that doesn't already have a request associated with it */
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
/* walk from head to tail */
qindex = (c_db->nodes[n].node_d.endpoints[e].recv_queue.head + i) % (MAX_QUEUE_ENTRIES);
if ((!c_db->nodes[n].node_d.endpoints[e].recv_queue.elements[qindex].request) &&
(!c_db->nodes[n].node_d.endpoints[e].recv_queue.elements[qindex].invalid)) {
mcapi_dprintf(4," receive request reserving qindex=%i\n",qindex);
c_db->nodes[n].node_d.endpoints[e].recv_queue.elements[qindex].request = request;
break;
}
}
if (i == MAX_QUEUE_ENTRIES) {
/* all of this endpoint's buffers already have reqeusts associated with them */
*mcapi_status = MCAPI_ENO_REQUEST;
request->completed = MCAPI_TRUE;
}
}
}
 
/***************************************************************************
NAME:mcapi_trans_display_state
DESCRIPTION: This function is useful for debugging. If the handle is null,
we'll print out the state of the entire database. Otherwise, we'll print out
only the state of the endpoint that the handle refers to.
PARAMETERS:
handle
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_display_state (void* handle)
{
/* lock the database */
// mcapi_trans_access_database_pre_nocheck();
mcapi_trans_display_state_internal(handle);
/* unlock the database */
// mcapi_trans_access_database_post_nocheck();
}
 
/***************************************************************************
NAME:mcapi_trans_display_state_internal
DESCRIPTION: This function is useful for debugging. If the handle is null,
we'll print out the state of the entire database. Otherwise, we'll print out
only the state of the endpoint that the handle refers to. Expects the database
to be locked.
PARAMETERS:
handle
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_display_state_internal (void* handle)
{
#ifdef __TCE__
return;
#else
uint16_t n,e,a;
mcapi_endpoint_t* endpoint = (mcapi_endpoint_t*)handle;
mcapi_boolean_t rv = MCAPI_FALSE;
printf("DISPLAY STATE:\n");
 
if (handle != NULL) {
/* print the data for the given endpoint */
rv = mcapi_trans_decode_handle_internal(*endpoint,&n,&e);
//assert(rv);
printf("node: %u, port: %u, receive queue (num_elements=%i):\n",
(unsigned)c_db->nodes[n].node_num,(unsigned)c_db->nodes[n].node_d.endpoints[e].port_num,
(unsigned)c_db->nodes[n].node_d.endpoints[e].recv_queue.num_elements);
printf(" endpoint: %d\n",e);
printf(" valid:%d\n",c_db->nodes[n].node_d.endpoints[e].valid);
printf(" anonymous:%d\n",c_db->nodes[n].node_d.endpoints[e].anonymous);
printf(" open:%d\n",c_db->nodes[n].node_d.endpoints[e].open);
printf(" connected:%d\n",c_db->nodes[n].node_d.endpoints[e].connected);
printf(" num_attributes:%d\n",(unsigned)c_db->nodes[n].node_d.endpoints[e].num_attributes);
for (a = 0; a < c_db->nodes[n].node_d.endpoints[e].num_attributes; a++) {
printf(" attribute:%d\n",a);
printf(" valid:%d\n",c_db->nodes[n].node_d.endpoints[e].attributes[a].valid);
printf(" attribute_num:%d\n",c_db->nodes[n].node_d.endpoints[e].attributes[a].attribute_num);
printf(" bytes:%i\n",(unsigned)c_db->nodes[n].node_d.endpoints[e].attributes[a].bytes);
}
print_queue(c_db->nodes[n].node_d.endpoints[e].recv_queue);
} else {
/* print the whole database */
for (n = 0; n < c_db->num_nodes; n++) {
printf("n=%d\n",n);
printf("node: %u\n",(unsigned)c_db->nodes[n].node_num);
printf(" valid:%d\n",c_db->nodes[n].valid);
printf(" finalized:%d\n",c_db->nodes[n].finalized);
printf(" num_endpoints:%d\n",c_db->nodes[n].node_d.num_endpoints);
for (e = 0; e < c_db->nodes[n].node_d.num_endpoints; e++) {
printf(" e=%d\n",e);
printf(" endpoint: %u\n",(unsigned)c_db->nodes[n].node_d.endpoints[e].port_num);
printf(" valid:%d\n",c_db->nodes[n].node_d.endpoints[e].valid);
printf(" anonymous:%d\n",c_db->nodes[n].node_d.endpoints[e].anonymous);
printf(" open:%d\n",c_db->nodes[n].node_d.endpoints[e].open);
printf(" connected:%d\n",c_db->nodes[n].node_d.endpoints[e].connected);
printf(" num_attributes:%u\n",(unsigned)c_db->nodes[n].node_d.endpoints[e].num_attributes);
for (a = 0; a < c_db->nodes[n].node_d.endpoints[e].num_attributes; a++) {
printf(" a=%d\n",a);
printf(" attribute:%d\n",a);
printf(" valid:%d\n",c_db->nodes[n].node_d.endpoints[e].attributes[a].valid);
printf(" attribute_num:%d\n",c_db->nodes[n].node_d.endpoints[e].attributes[a].attribute_num);
printf(" bytes:%u\n",(unsigned)c_db->nodes[n].node_d.endpoints[e].attributes[a].bytes);
}
print_queue(c_db->nodes[n].node_d.endpoints[e].recv_queue);
}
}
}
printf("\n\n");
#endif
}
 
 
/***************************************************************************
NAME:check_get_endpt_request
DESCRIPTION: Checks if the request to get an endpoint has been completed or not.
PARAMETERS: the request pointer (to be filled in)
RETURN VALUE: none
***************************************************************************/
void check_get_endpt_request (mcapi_request_t *request)
{
/* lock the database */
// mcapi_trans_access_database_pre();
 
if (mcapi_trans_get_endpoint_internal (request->endpoint, request->node_num,
request->port_num)) {
request->completed = MCAPI_TRUE;
request->status = MCAPI_SUCCESS;
}
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME: cancel_receive_request
DESCRIPTION: Cancels an outstanding receive request. This is a little tricky
because we have to preserve FIFO which means we have to shift all other
outstanding receive requests down.
PARAMETERS:
request -
RETURN VALUE: none
***************************************************************************/
void cancel_receive_request (mcapi_request_t *request)
{
uint16_t rn,re;
int i,last,start,curr;
mcapi_boolean_t rv = MCAPI_FALSE;
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(request->handle,&rn,&re);
//assert(rv);
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].request == request) {
/* we found the request, now clear the reservation */
mcapi_dprintf(5,"cancel_receive_request - cancelling request at index %i\n BEFORE:",i);
print_queue(c_db->nodes[rn].node_d.endpoints[re].recv_queue);
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].request = NULL;
break;
}
}
 
/* we should have found the outstanding request */
//assert (i != MAX_QUEUE_ENTRIES);
 
/* shift all pending reservations down*/
start = i;
last = start;
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
curr = (i+start)%MAX_QUEUE_ENTRIES;
/* don't cross over the head or the tail */
if ((curr == c_db->nodes[rn].node_d.endpoints[re].recv_queue.tail) &&
(curr != start)) {
break;
}
if ((curr == c_db->nodes[rn].node_d.endpoints[re].recv_queue.head) &&
(curr != start)) {
break;
}
if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[curr].request) {
mcapi_dprintf(5,"cancel_receive_request - shifting request at index %i to index %i\n",curr,last);
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[last].request =
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[curr].request;
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[curr].request = NULL;
last = curr;
}
}
request->cancelled = MCAPI_TRUE;
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME: check_receive_request
DESCRIPTION: Checks if the given non-blocking receive request has completed.
This is a little tricky because we can't just pop from the head of the
endpoints receive queue. We have to locate the reservation that was
made in the queue (to preserve FIFO) at the time the request was made.
PARAMETERS: the request pointer (to be filled in
RETURN VALUE: none
***************************************************************************/
void check_receive_request (mcapi_request_t *request)
{
uint16_t rn,re;
int i;
size_t size;
mcapi_boolean_t rv = MCAPI_FALSE;
 
/* lock the database */
// mcapi_trans_access_database_pre();
 
rv = mcapi_trans_decode_handle_internal(request->handle,&rn,&re);
//assert(rv);
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].request == request) {
/* we found the request, check to see if there is valid data in the receive queue entry */
if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].b) {
/* clear the request reservation */
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].request = NULL;
/* the buffer better still exist */
//assert (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].b->in_use);
/* update the request */
request->completed = MCAPI_TRUE;
request->status = MCAPI_SUCCESS;
/* first take the entry out of the queue this has the potential to fragment our
receive queue since we may not be removing from the head */
if ( c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_PKT_CHAN) {
/* packet buffer means system buffer, so save the users pointer to the buffer */
mcapi_trans_recv_internal_ (rn,re,request->buffer_ptr,request->size,&request->size,i,NULL);
} else {
/* message buffer means user buffer, so save the users buffer */
size = request->size;
mcapi_trans_recv_internal_ (rn,re,&request->buffer,request->size,&request->size,i,NULL);
if (request->size > size) {
request->size = size;
request->status = MCAPI_ETRUNCATED;
}
}
/* now update the receive queue state */
c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements--;
/* mark this entry as invalid so that the "bubble" won't be re-used */
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[i].invalid = MCAPI_TRUE;
mcapi_trans_compact_queue (&c_db->nodes[rn].node_d.endpoints[re].recv_queue);
mcapi_dprintf(4," receive request (test/wait) popped from qindex=%i, num_elements=%i, head=%i, tail=%i\n",
i,c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements,
c_db->nodes[rn].node_d.endpoints[re].recv_queue.head,
c_db->nodes[rn].node_d.endpoints[re].recv_queue.tail);
}
break;
}
}
/* we should have found the outstanding request */
//assert (i != MAX_QUEUE_ENTRIES);
 
/* unlock the database */
// mcapi_trans_access_database_post();
}
 
/***************************************************************************
NAME:mcapi_trans_connect_channel_internal
DESCRIPTION: connects a channel
PARAMETERS:
send_endpoint
receive_endpoint
type
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_connect_channel_internal (mcapi_endpoint_t send_endpoint,
mcapi_endpoint_t receive_endpoint,channel_type type)
{
uint16_t sn,se;
uint16_t rn,re;
mcapi_boolean_t rv = MCAPI_FALSE;
/* the database should already be locked */
 
rv = mcapi_trans_decode_handle_internal(send_endpoint,&sn,&se);
//assert(rv);
rv = mcapi_trans_decode_handle_internal(receive_endpoint,&rn,&re);
//assert(rv);
 
/* update the send endpoint */
c_db->nodes[sn].node_d.endpoints[se].connected = MCAPI_TRUE;
c_db->nodes[sn].node_d.endpoints[se].recv_queue.recv_endpt = receive_endpoint;
c_db->nodes[sn].node_d.endpoints[se].recv_queue.send_endpt = send_endpoint;
c_db->nodes[sn].node_d.endpoints[se].recv_queue.channel_type = type;
 
/* update the receive endpoint */
c_db->nodes[rn].node_d.endpoints[re].connected = MCAPI_TRUE;
c_db->nodes[rn].node_d.endpoints[re].recv_queue.send_endpt = send_endpoint;
c_db->nodes[rn].node_d.endpoints[re].recv_queue.recv_endpt = receive_endpoint;
c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type = type;
 
 
mcapi_dprintf(1," channel_type=%d connected sender (node=%d,port=%d) to receiver (node=%d,port=%d)\n",
type,c_db->nodes[sn].node_num,c_db->nodes[sn].node_d.endpoints[se].port_num,
c_db->nodes[rn].node_num,c_db->nodes[rn].node_d.endpoints[re].port_num);
}
 
/***************************************************************************
NAME:mcapi_trans_send_internal
DESCRIPTION: Attempts to send a message from one endpoint to another
PARAMETERS:
sn - the send node index (only used for verbose debug print)
se - the send endpoint index (only used for verbose debug print)
rn - the receive node index
re - the receive endpoint index
buffer -
buffer_size -
blocking - whether or not this is a blocking send (currently not used!)
RETURN VALUE: true/false indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_send_internal (
uint16_t sn,uint16_t se, uint16_t rn, uint16_t re,
char* buffer, size_t buffer_size,mcapi_boolean_t blocking,uint64_t scalar)
{
int qindex,i;
buffer_entry* db_buff = NULL;
mcapi_dprintf(3," mcapi_trans_send_internal sender (node=%d,port=%d) to receiver (node=%d,port=%d)\n",
c_db->nodes[sn].node_num,c_db->nodes[sn].node_d.endpoints[se].port_num,
c_db->nodes[rn].node_num,c_db->nodes[rn].node_d.endpoints[re].port_num);
 
/* The database should already be locked! */
 
/* Note: the blocking parameter is not used.
I'm not sure if I'm implementing blocking sends correctly. They can still
return ENO_BUFFER, so it doesn't look from the spec like they are supposed to block
until a buffer is free. A blocking receive blocks on an empty queue until there is
something available, but a blocking send does not block on a full queue. Is that correct? */
if (mcapi_trans_full_queue(c_db->nodes[rn].node_d.endpoints[re].recv_queue)) {
/* we couldn't get space in the endpoints receive queue, try to compact the queue */
mcapi_trans_compact_queue(&c_db->nodes[rn].node_d.endpoints[re].recv_queue);
return MCAPI_FALSE;
}
/* find a free mcapi buffer (we only have to worry about this on the sending side) */
for (i = 0; i < MAX_BUFFERS; i++) {
if (!c_db->buffers[i].in_use) {
c_db->buffers[i].in_use = MCAPI_TRUE;
c_db->buffers[i].magic_num = MAGIC_NUM;
db_buff = &c_db->buffers[i];
break;
}
}
if (i == MAX_BUFFERS) {
/* we couldn't get a free buffer */
mcapi_dprintf(2," ERROR mcapi_trans_send_internal: No more buffers available - try freeing some buffers. \n");
return MCAPI_FALSE;
}
 
/* now go about updating buffer into the database... */
/* find the next index in the circular queue */
qindex = mcapi_trans_push_queue(&c_db->nodes[rn].node_d.endpoints[re].recv_queue);
mcapi_dprintf(4," send pushing %u byte buffer to qindex=%i, num_elements=%i, head=%i, tail=%i\n",
buffer_size,qindex,c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements,
c_db->nodes[rn].node_d.endpoints[re].recv_queue.head,
c_db->nodes[rn].node_d.endpoints[re].recv_queue.tail);
/* printf(" send pushing to qindex=%i\n",qindex); */
if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_SCL_CHAN ) {
db_buff->scalar = scalar;
} else {
/* copy the buffer parm into a mcapi buffer */
memcpy (db_buff->buff,buffer,buffer_size);
}
/* set the size */
db_buff->size = buffer_size;
/* update the ptr in the receive_endpoints queue to point to our mcapi buffer */
c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b = db_buff;
 
return MCAPI_TRUE;
}
 
/***************************************************************************
NAME: mcapi_trans_recv_internal_
DESCRIPTION: Removes a message (at the given qindex) from the given
receive endpoints queue. This function is used both by check_receive_request
and mcapi_trans_recv_internal. We needed to separate the functionality
because in order to preserve FIFO, if recv was called to an empty queue we
had to set a reservation at the head of the queue. Thus we can't always
just pop from the head of the queue.
PARAMETERS:
rn - the receive node index
re - the receive endpoint index
buffer -
buffer_size -
received_size - the actual size (in bytes) of the data received
qindex - index into the receive endpoints queue that we should remove from
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_recv_internal_ (
uint16_t rn, uint16_t re, void** buffer, size_t buffer_size,
size_t* received_size,int qindex,uint64_t* scalar)
{
/* size_t size; */
/* int i; */
 
/* /\* the database should already be locked! *\/ */
/* mcapi_dprintf(3," mcapi_trans_recv_internal_ for receiver (node=%d,port=%d)\n", */
/* c_db->nodes[rn].node_num,c_db->nodes[rn].node_d.endpoints[re].port_num); */
/* /\* printf(" recv popping from qindex=%i\n",qindex); *\/ */
/* /\* first make sure buffer is big enough for the message *\/ */
/* if ((buffer_size) < c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->size) { */
/* fprintf(stderr,"ERROR: mcapi_trans_recv_internal buffer not big enough - loss of data: buffer_size=%i, element_size=%i\n", */
/* (int)buffer_size, */
/* (int)c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->size); */
/* /\* NOTE: MCAPI_ETRUNCATED will be set by the calling functions by noticing that buffer_size < received_size *\/ */
/* } */
/* /\* set the size *\/ */
/* size = c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->size; */
/* /\* fill in the size *\/ */
/* *received_size = size; */
/* if (buffer_size < size) { */
/* size = buffer_size; */
/* } */
/* mcapi_dprintf(4," receive popping %u byte buffer from qindex=%i, num_elements=%i, head=%i, tail=%i\n", */
/* size,qindex,c_db->nodes[rn].node_d.endpoints[re].recv_queue.num_elements, */
/* c_db->nodes[rn].node_d.endpoints[re].recv_queue.head, */
/* c_db->nodes[rn].node_d.endpoints[re].recv_queue.tail); */
/* /\* copy the buffer out of the receive_endpoint's queue and into the buffer parm *\/ */
/* if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_PKT_CHAN) { */
/* /\* mcapi supplied buffer (pkt receive), so just update the pointer *\/ */
/* *buffer = c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->buff; */
/* } else { */
/* /\* user supplied buffer, copy it in and free the mcapi buffer *\/ */
/* if (c_db->nodes[rn].node_d.endpoints[re].recv_queue.channel_type == MCAPI_SCL_CHAN) { */
/* /\* scalar receive *\/ */
/* *scalar = c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->scalar; */
/* } else { */
/* /\* msg receive *\/ */
/* memcpy (*buffer,c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->buff,size); */
/* } */
/* /\* free the mcapi message buffer *\/ */
/* for (i = 0; i < MAX_BUFFERS; i++) { */
/* if ((c_db->buffers[i].in_use) && */
/* (c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b->buff == */
/* c_db->buffers[i].buff)) { */
/* c_db->buffers[i].in_use = MCAPI_FALSE; */
/* break; */
/* } */
/* /\* we should have found it *\/ */
/* //assert (i != MAX_BUFFERS); */
/* } */
/* } */
/* /\* clear the buffer pointer in the receive queue entry *\/ */
/* c_db->nodes[rn].node_d.endpoints[re].recv_queue.elements[qindex].b = NULL; */
 
}
 
/***************************************************************************
NAME: mcapi_trans_recv_internal
DESCRIPTION: checks if a message is available, if so performs the pop (from
the head of the queue) and sends the qindex to be used to mcapi_trans_recv_internal_
PARAMETERS:
rn - the receive node index
re - the receive endpoint index
buffer -
buffer_size -
received_size - the actual size (in bytes) of the data received
blocking - whether or not this is a blocking receive
RETURN VALUE: true/false indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_recv_internal (
uint16_t rn, uint16_t re, void** buffer,
size_t buffer_size, size_t* received_size,
mcapi_boolean_t blocking,uint64_t* scalar)
{
int qindex;
/* The database should already be locked! */
if ((!blocking) && (mcapi_trans_empty_queue(c_db->nodes[rn].node_d.endpoints[re].recv_queue))) {
return MCAPI_FALSE;
}
while (mcapi_trans_empty_queue(c_db->nodes[rn].node_d.endpoints[re].recv_queue)) {
mcapi_dprintf(5,"mcapi_trans_recv_internal to empty queue - attempting to yield\n");
/* we have the lock, use this yield */
transport_sm_yield_internal();
}
/* remove the element from the receive endpoints queue */
qindex = mcapi_trans_pop_queue(&c_db->nodes[rn].node_d.endpoints[re].recv_queue);
mcapi_trans_recv_internal_ (rn,re,buffer,buffer_size,received_size,qindex,scalar);
 
return MCAPI_TRUE;
}
 
/***************************************************************************
NAME: mcapi_trans_open_channel_internal
DESCRIPTION: marks the given endpoint as open
PARAMETERS:
n - the node index
e - the endpoint index
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_open_channel_internal (uint16_t n, uint16_t e)
{
/* The database should already be locked! */
 
/* mark the endpoint as open */
c_db->nodes[n].node_d.endpoints[e].open = MCAPI_TRUE;
}
 
/***************************************************************************
NAME:mcapi_trans_close_channel_internal
DESCRIPTION: marks the given endpoint as closed
PARAMETERS:
n - the node index
e - the endpoint index
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_close_channel_internal (uint16_t n, uint16_t e)
{
/* The database should already be locked! */
/* mark the endpoint as closed */
c_db->nodes[n].node_d.endpoints[e].open = MCAPI_FALSE;
}
 
/***************************************************************************
NAME:transport_sm_yield_internal
DESCRIPTION: releases the lock, attempts to yield, re-acquires the lock.
PARAMETERS: none
RETURN VALUE: none
***************************************************************************/
void transport_sm_yield_internal ()
{
/* call this version of sched_yield when you have the lock */
/* release the lock */
// mcapi_trans_access_database_post();
//sched_yield();
/* re-acquire the lock */
// mcapi_trans_access_database_pre();
}
 
/***************************************************************************
NAME: mcapi_trans_access_database_pre_nocheck
DESCRIPTION: The first node that calls initialize can't do the balanced
lock/unlock checking because it hasn't registered itself yet. Thus
the need for a nocheck version of this function. This function
acquires the semaphore.
PARAMETERS: none
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_access_database_pre_nocheck ()
{
/* acquire the semaphore, this is a blocking function */
//transport_sm_lock_semaphore(sem_id);
}
 
/***************************************************************************
NAME: mcapi_trans_access_database_pre
DESCRIPTION: This function acquires the semaphore.
PARAMETERS: none
RETURN VALUE:none
***************************************************************************/
void mcapi_trans_access_database_pre ()
{
/* int i = 0; */
/* int pid = 0; */
/* pthread_t tid = 0; */
/* /\* first acquire the semaphore, this is a blocking function *\/ */
/* transport_sm_lock_semaphore(sem_id); */
/* if (mcapi_debug > 5) { */
/* /\* turn on balanced semaphore lock/unlock checking *\/ */
/* i = get_private_data_index(); */
/* assert (d[i].have_lock == MCAPI_FALSE); */
/* pid = d[i].pid; */
/* tid = d[i].tid; */
/* d[i].have_lock = MCAPI_TRUE; */
/* mcapi_dprintf(7," PID:%d TID%u got lock\n",pid,(unsigned long)tid); */
/* } */
 
}
 
/***************************************************************************
NAME:mcapi_trans_access_database_post_nocheck
DESCRIPTION:The first node that calls initialize can't do the balanced
lock/unlock checking because it hasn't registered itself yet. Thus
the need for a nocheck version of this function. This function
releases the semaphore.
PARAMETERS: none
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_access_database_post_nocheck ()
{
/* release the semaphore, this should always work */
//assert (transport_sm_unlock_semaphore(sem_id));
}
 
/***************************************************************************
NAME:mcapi_trans_access_database_post
DESCRIPTION: This function releases the semaphore.
PARAMETERS: none
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_access_database_post ()
{
/* int i = 0; */
/* int pid = 0;; */
/* pthread_t tid = 0; */
/* if (mcapi_debug > 5) { */
/* /\* turn on balanced semaphore lock/unlock checking *\/ */
/* i = get_private_data_index(); */
/* assert (d[i].have_lock == MCAPI_TRUE); */
/* pid = d[i].pid; */
/* tid = d[i].tid; */
/* d[i].have_lock = MCAPI_FALSE; */
/* mcapi_dprintf(7," PID:%d TID%u released lock\n",pid,(unsigned long)tid); */
/* } */
/* /\* finally, release the semaphore, this should always work *\/ */
/* assert (transport_sm_unlock_semaphore(sem_id)); */
}
 
/***************************************************************************
NAME:mcapi_trans_add_node
DESCRIPTION: Adds a node to the database (called by intialize)
PARAMETERS: node_num
RETURN VALUE: true/false indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_add_node (mcapi_uint_t node_num)
{
mcapi_boolean_t rc = MCAPI_TRUE;
 
/* lock the database */
//mcapi_trans_access_database_pre_nocheck();
 
/* mcapi should have checked that the node doesn't already exist */
 
if (c_db->num_nodes == MAX_NODES) {
rc = MCAPI_FALSE;
}
 
if (rc) {
/* setup our local (private data) */
/* we do this while we have the lock because we don't want an inconsistency/
race condition where the node exists in the database but not yet in
the transport layer's cached state */
mcapi_trans_set_node_num(node_num);
/* add the node */
c_db->nodes[c_db->num_nodes].finalized = MCAPI_FALSE;
c_db->nodes[c_db->num_nodes].valid = MCAPI_TRUE;
c_db->nodes[c_db->num_nodes].node_num = node_num;
c_db -> num_nodes++;
}
 
/* unlock the database */
// mcapi_trans_access_database_post_nocheck();
 
return rc;
}
 
/***************************************************************************
NAME:mcapi_trans_encode_handle_internal
DESCRIPTION:
Our handles are very simple - a 32 bit integer is encoded with
an index (16 bits gives us a range of 0:64K indices).
Currently, we only have 2 indices for each of: node array and
endpoint array.
PARAMETERS:
node_index -
endpoint_index -
RETURN VALUE: the handle
***************************************************************************/
uint32_t mcapi_trans_encode_handle_internal (uint16_t node_index,uint16_t endpoint_index)
{
/* The database should already be locked */
uint32_t handle = 0;
uint8_t shift = 16;
 
//assert ((node_index < MAX_NODES) && (endpoint_index < MAX_ENDPOINTS));
 
handle = node_index;
handle <<= shift;
handle |= endpoint_index;
 
return handle;
}
 
/***************************************************************************
NAME:mcapi_trans_decode_handle_internal
DESCRIPTION: Decodes the given handle into it's database indices
PARAMETERS:
handle -
node_index -
endpoint_index -
RETURN VALUE: true/false indicating success or failure
***************************************************************************/
mcapi_boolean_t mcapi_trans_decode_handle_internal (uint32_t handle, uint16_t *node_index,
uint16_t *endpoint_index)
{
//int rc = MCAPI_FALSE;
uint8_t shift = 16;
/* The database should already be locked */
*node_index = (handle & 0xffff0000) >> shift;
*endpoint_index = (handle & 0x0000ffff);
 
if (*node_index >= MAX_NODES || *endpoint_index >= MAX_ENDPOINTS) {
return MCAPI_FALSE;
}
 
if (*node_index == my_node_id &&
!(c_db->nodes[*node_index].node_d.endpoints[*endpoint_index].valid)) {
return MCAPI_FALSE;
}
return MCAPI_TRUE;
}
 
/***************************************************************************
NAME: mcapi_trans_set_node_num
DESCRIPTION: sets the node_num
PARAMETERS: n: the node_num
RETURN VALUE: boolean indicating success (there was room in our data array) or failure
(couldn't find a free entry to set the node_num)
***************************************************************************/
mcapi_boolean_t mcapi_trans_set_node_num(mcapi_uint_t n)
{
/* /\* note: an optimization to searching this structure would be for */
/* mcapi_initialize to return a handle that we could just use to */
/* index. *\/ */
/* int i; */
/* for (i = 0; i < MAX_ENDPOINTS; i++) { */
/* /\* assume pid=0 means this entry is not being used *\/ */
/* if (!d[i].pid) { */
/* d[i].pid = getpid(); */
/* d[i].tid = pthread_self(); */
/* d[i].node_num = n; */
 
/* mcapi_dprintf(1," Adding node: NODE:%u PID:%u TID:%u\n",n,(int)d[i].pid, */
/* (unsigned long)d[i].tid); */
/* return MCAPI_TRUE; */
/* } */
/* } */
/* assert(!"we should never get here"); */
return MCAPI_FALSE;
}
 
/***************************************************************************
NAME: mcapi_trans_get_node_index
DESCRIPTION: Returns the index into our database corresponding to the node_num
PARAMETERS: n: the node_num
RETURN VALUE:
***************************************************************************/
mcapi_boolean_t mcapi_trans_get_node_index(mcapi_uint_t node_num)
{
/* /\* look up the node *\/ */
/* int i; */
/* uint32_t node_index = MAX_NODES; */
/* for (i = 0; i < c_db->num_nodes; i++) { */
/* if (c_db->nodes[i].node_num == node_num) { */
/* node_index = i; */
/* break; */
/* } */
/* } */
/* assert (node_index != MAX_NODES); */
return node_num;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//////////////////////////////////////////////////////////////////////////////
// //
// queue management //
// //
//////////////////////////////////////////////////////////////////////////////
/***************************************************************************
NAME: print_queue
DESCRIPTION: Prints an endpoints receive queue (useful for debugging)
PARAMETERS: q - the queue
RETURN VALUE: none
***************************************************************************/
void print_queue (queue q)
{
#ifdef __TCE__
return;
#else
int i,qindex;
/*print the recv queue from head to tail*/
printf(" recv_queue:\n");
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
/* walk the queue from the head to the tail */
qindex = (q.head + i) % (MAX_QUEUE_ENTRIES);
printf(" ----------------QINDEX: %i",qindex);
if (q.head == qindex) { printf(" *** HEAD ***"); }
if (q.tail == qindex) { printf(" *** TAIL ***"); }
printf("\n request:0x%lx\n",(long unsigned int)q.elements[qindex].request);
if (q.elements[qindex].request) {
printf(" valid:%u\n",q.elements[qindex].request->valid);
printf(" size:%u\n",(int)q.elements[qindex].request->size);
switch (q.elements[qindex].request->type) {
case (OTHER_REQUEST): printf(" type:OTHER\n"); break;
case (SEND): printf(" type:SEND\n"); break;
case (RECV): printf(" type:RECV\n"); break;
case (GET_ENDPT): printf(" type:GET_ENDPT\n"); break;
default: printf(" type:UNKNOWN!!!\n"); break;
};
printf(" buffer:[%s]\n",(char*)q.elements[qindex].request->buffer);
printf(" buffer_ptr:0x%lx\n",(long unsigned int)q.elements[qindex].request->buffer_ptr);
printf(" completed:%u\n",q.elements[qindex].request->completed);
printf(" cancelled:%u\n",q.elements[qindex].request->cancelled);
printf(" handle:0x%i\n",(int)q.elements[qindex].request->handle);
/* printf(" status:%s\n",mcapi_display_status(q.elements[qindex].request->status)); */
printf(" status:%i\n",(int)q.elements[qindex].request->status);
printf(" endpoint:0x%lx\n",(long unsigned int)q.elements[qindex].request->endpoint);
}
printf(" invalid:%u\n",q.elements[qindex].invalid);
printf(" b:0x%lx\n",(long unsigned int)q.elements[qindex].b);
if (q.elements[qindex].b) {
printf(" size:%u\n",(unsigned)q.elements[qindex].b->size);
printf(" in_use:%u\n",q.elements[qindex].b->in_use);
printf(" buff:[%s]\n\n",(char*)q.elements[qindex].b->buff);
}
}
#endif
}
 
/***************************************************************************
NAME: push_queue
DESCRIPTION: Returns the qindex that should be used for adding an element.
Also updates the num_elements, and tail pointer.
PARAMETERS: q - the queue pointer
RETURN VALUE: the qindex to be used
***************************************************************************/
int mcapi_trans_push_queue(queue* q)
{
int i;
if ( (q->tail + 1) % MAX_QUEUE_ENTRIES == q->head) {
/* assert (q->num_elements == MAX_QUEUE_ENTRIES);*/
//assert(!"push_queue called on full queue\n");
}
q->num_elements++;
i = q->tail;
q->tail = ++q->tail % MAX_QUEUE_ENTRIES;
//assert (q->head != q->tail);
return i;
}
 
/***************************************************************************
NAME: pop_queue
DESCRIPTION: Returns the qindex that should be used for removing an element.
Also updates the num_elements, and head pointer.
PARAMETERS: q - the queue pointer
RETURN VALUE: the qindex to be used
***************************************************************************/
int mcapi_trans_pop_queue (queue* q)
{
int i,qindex;
int x = 0;
 
if (q->head == q->tail) {
/*assert (q->num_elements == 0);*/
//assert (!"pop_queue called on empty queue\n");
}
/* we can't just pop the first element off the head of the queue, because it
may be reserved for an earlier recv call, we need to take the first element
that doesn't already have a request associated with it. This can fragment
our queue. */
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
/* walk the queue from the head to the tail */
qindex = (q->head + i) % (MAX_QUEUE_ENTRIES);
if ((!q->elements[qindex].request) &&
(q->elements[qindex].b)){
x = qindex;
break;
}
}
if (i == MAX_QUEUE_ENTRIES) {
/* all of this endpoint's buffers already have requests associated with them */
//assert(0); /* mcapi_trans_empty_queue should have already checked for this case */
}
 
q->num_elements--;
 
/* if we are removing from the front of the queue, then move head */
if (x == q->head) {
q->head = ++q->head % MAX_QUEUE_ENTRIES;
} else {
/* we are fragmenting the queue, mark this entry as invalid */
q->elements[qindex].invalid = MCAPI_TRUE;
}
 
if (q->num_elements > 0) {
//assert (q->head != q->tail);
}
 
mcapi_trans_compact_queue (q);
 
return x;
}
 
/***************************************************************************
NAME: compact_queue
DESCRIPTION: Attempts to compact the queue. It can become fragmented based
on the order that blocking/non-blocking sends/receives/tests come in
PARAMETERS: q - the queue pointer
RETURN VALUE: none
***************************************************************************/
void mcapi_trans_compact_queue (queue* q)
{
int i;
int qindex;
 
mcapi_dprintf(7,"before mcapi_trans_compact_queue head=%i,tail=%i,num_elements=%i\n",q->head,q->tail,q->num_elements);
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
qindex = (q->head + i) % (MAX_QUEUE_ENTRIES);
if ((qindex == q->tail) ||
(q->elements[qindex].request) ||
(q->elements[qindex].b)){
break;
} else {
/* advance the head pointer */
q->elements[qindex].invalid = MCAPI_FALSE;
q->head = ++q->head % MAX_QUEUE_ENTRIES;
i--;
}
}
mcapi_dprintf(7,"after mcapi_trans_compact_queue head=%i,tail=%i,num_elements=%i\n",q->head,q->tail,q->num_elements);
if (q->num_elements > 0) {
//assert (q->head != q->tail);
}
 
}
 
 
/***************************************************************************
NAME: mcapi_trans_empty_queue
DESCRIPTION: Checks if the queue is empty or not
PARAMETERS: q - the queue
RETURN VALUE: true/false
***************************************************************************/
mcapi_boolean_t mcapi_trans_empty_queue (queue q)
{
int i,qindex;
if (q.head == q.tail) {
/* assert (q.num_elements == 0); */
return MCAPI_TRUE;
}
/* if we have any buffers in our queue that don't have
reservations, then our queue is non-empty */
for (i = 0; i < MAX_QUEUE_ENTRIES; i++) {
qindex = (q.head + i) % (MAX_QUEUE_ENTRIES);
if ((!q.elements[qindex].request) &&
(q.elements[qindex].b)){
break;
}
}
if (i == MAX_QUEUE_ENTRIES) {
return MCAPI_TRUE;
}
 
return MCAPI_FALSE;
}
 
/***************************************************************************
NAME: mcapi_trans_full_queue
DESCRIPTION: Checks if the queue is full or not
PARAMETERS: q - the queue
RETURN VALUE: true/false
***************************************************************************/
mcapi_boolean_t mcapi_trans_full_queue (queue q)
{
if ( (q.tail + 1) % MAX_QUEUE_ENTRIES == q.head) {
/* assert (q.num_elements == (MAX_QUEUE_ENTRIES -1)); */
return MCAPI_TRUE;
}
return MCAPI_FALSE;
}
 
 
 
 
 
 
 
 
/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/trans_hibi_fdev.h
0,0 → 1,160
/*
Copyright (c) 2008, The Multicore Association
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
 
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
(3) Neither the name of the Multicore Association nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
// **************************************************************************
// File : transport_nios.h
// Author : Lauri Matilainen
// Date : 17.09.2010
// Decription : FUNCAPI transport layer implementation for NIOS II
// (modified from The Multicore Association example
// shared memory implementation)
// Version history : 17.09.2005 Lauri Matilainen 1st mod version
//
//
//
//
// **************************************************************************
 
 
 
#ifndef _TRANS_HIBI_FDEV_H_
#define _TRANS_HIBI_FDEV_H_
 
#include "mcapi_datatypes.h"
#include "mcapi_config.h"
 
#include <stdarg.h> /* for va_list */
#include <stdio.h> /* for the inlined dprintf routine */
 
 
/*******************************************************************
definitions and constants
*******************************************************************/
/* the debug level */
extern int mcapi_debug;
 
/* we leave one empty element so that the array implementation
can tell the difference between empty and full */
 
#define MAX_QUEUE_ENTRIES (MAX_QUEUE_ELEMENTS + 1)
 
 
/*******************************************************************
mcapi_trans data types
*******************************************************************/
/* buffer entry is used for msgs, pkts and scalars */
/* NOTE: if you change the buffer_entry data structure then you also
need to update the pointer arithmetic in mcapi_trans_pktchan_free */
typedef struct {
uint32_t magic_num;
uint32_t size; /* size (in bytes) of the buffer */
mcapi_boolean_t in_use;
char buff [MAX_PKT_SIZE];
uint64_t scalar;
} buffer_entry;
 
typedef struct {
mcapi_request_t* request; /* holds a reservation for an outstanding receive request */
buffer_entry* b; /* the pointer to the actual buffer entry in the buffer pool */
mcapi_boolean_t invalid;
} buffer_descriptor;
 
 
typedef struct {
mcapi_boolean_t valid;
uint16_t attribute_num;
uint32_t bytes;
void* attribute_d;
} attribute_entry;
 
typedef struct {
/* the next 3 data members are only valid for channels */
mcapi_endpoint_t send_endpt;
mcapi_endpoint_t recv_endpt;
uint8_t channel_type;
 
uint32_t num_elements;
uint16_t head;
uint16_t tail;
buffer_descriptor elements[MAX_QUEUE_ENTRIES+1];
}queue;
 
 
typedef struct {
uint32_t port_num;
mcapi_boolean_t valid;
mcapi_boolean_t anonymous;
mcapi_boolean_t open;
mcapi_boolean_t connected;
uint32_t num_attributes;
attribute_entry attributes [MAX_ATTRIBUTES];
queue recv_queue;
} endpoint_entry;
 
typedef struct {
uint16_t num_endpoints;
endpoint_entry endpoints[MAX_ENDPOINTS];
} node_descriptor;
 
typedef struct {
uint32_t node_num;
mcapi_boolean_t finalized;
mcapi_boolean_t valid;
node_descriptor node_d;
} node_entry;
 
 
typedef struct {
uint16_t num_nodes;
node_entry nodes[MAX_NODES];
buffer_entry buffers [MAX_BUFFERS];
} mcapi_database;
 
 
/* debug printing */
/* Inline this (and define in header) so that it can be compiled out if WITH_DEBUG is 0 */
inline void mcapi_dprintf(int level,const char *format, ...) {
if (WITH_DEBUG) {
va_list ap;
va_start(ap,format);
if (level <= mcapi_debug){
printf("MCAPI_DEBUG:");
/* call variatic printf */
vprintf(format,ap);
}
va_end(ap);
}
}
 
 
 
#endif
/funbase_ip_library/trunk/TUT/ip.swp.api/mcapi_transport_hibi_fdev/1.0/src/mcapi_datatypes.h
0,0 → 1,170
/*
Copyright (c) 2008, The Multicore Association
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
 
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
(3) Neither the name of the Multicore Association nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef MCAPI_DATATYPES_H
#define MCAPI_DATATYPES_H
 
#include "mcapi_config.h"
 
#include <stddef.h> /* for size_t */
#include <stdint.h>
 
 
/******************************************************************
definitions and constants
******************************************************************/
#ifndef MCAPI_PORT_ANY
#define MCAPI_PORT_ANY 0xffffffff
#endif
 
#ifndef MCAPI_INFINITE
#define MCAPI_INFINITE 0xffffffff
#endif
 
#ifndef MCAPI_MAX_PRIORITY
#define MCAPI_MAX_PRIORITY 10
#endif
 
#define MCAPI_TRUE 1
#define MCAPI_FALSE 0
 
#define MCAPI_NULL NULL
 
#define MCAPI_OUT
/* could define this one as const */
#define MCAPI_IN
 
#ifndef MAX_QUEUE_ELEMENTS
#define MAX_QUEUE_ELEMENTS 64
#endif
 
/******************************************************************
datatypes
******************************************************************/
/* error codes */
typedef enum {
MCAPI_INCOMPLETE,
MCAPI_SUCCESS,
MCAPI_ENO_INIT, /* The MCAPI environment could not be initialized. */
MCAPI_ENO_FINAL, /* The MCAPI environment could not be finalized. */
MCAPI_ENOT_ENDP, /* Argument is not an endpoint descriptor. */
MCAPI_EMESS_LIMIT, /* The message size exceeds the maximum size allowed by the MCAPI implementation. */
MCAPI_ENO_BUFFER, /* No more message buffers available. */
MCAPI_ENO_REQUEST, /* No more request handles available. */
MCAPI_ENO_MEM, /* No memory available. */
MCAPI_ENODE_NOTINIT, /* The node is not initialized. */
MCAPI_EEP_NOTALLOWED, /* Endpoints cannot be created on this node. */
MCAPI_EPORT_NOTVALID, /* The parameter is not a valid port */
MCAPI_ENODE_NOTVALID, /* The parameter is not a valid node. */
MCAPI_ENO_ENDPOINT, /* No such endpoint exists */
MCAPI_ENOT_OWNER, /* This node does not own the given endpoint */
MCAPI_ECHAN_OPEN, /* A channel is open on this endpoint */
MCAPI_ECONNECTED, /* A channel connection has already been established for the given endpoint.*/
MCAPI_EATTR_INCOMP, /* Connection of endpoints with incompatible attributes not allowed.*/
MCAPI_ECHAN_TYPE, /* Attempt to open a packet channel on an endpoint that has been connected with a different channel type.*/
MCAPI_EDIR, /* Attempt to open a send handle on a port that was connected as a receiver, or vice versa.*/
MCAPI_ENOT_HANDLE, /* Argument is not a channel handle.*/
MCAPI_EPACK_LIMIT, /* The message size exceeds the maximum size allowed by the MCAPI implementation.*/
MCAPI_ENOT_VALID_BUF, /* Argument is not a valid buffer descriptor} flags; */
MCAPI_ENOT_OPEN, /* The endpoint is not open. */
MCAPI_EREQ_CANCELED, /* The request has been cancelled */
MCAPI_ENOTREQ_HANDLE, /* Invalid request handle */
MCAPI_EENDP_ISCREATED,/* The endpoint has already been created */
MCAPI_EENDP_LIMIT, /* Max endpoints already exist - no more can be created at this time */
MCAPI_ENOT_CONNECTED, /* The endpoint is not connected */
MCAPI_ESCL_SIZE, /* Scalar size mismatch - send/recv called with differing sizes */
MCAPI_EPRIO, /* Incorrect priority level */
MCAPI_INITIALIZED, /* This node has already called initialize */
MCAPI_EPARAM, /* Invalid parameter */
MCAPI_ETRUNCATED, /* The buffer has been truncated */
MCAPI_EREQ_TIMEOUT, /* The request timed out */
} mcapi_status_flags;
 
/* basic types */
typedef int32_t mcapi_int_t;
typedef uint32_t mcapi_uint_t;
typedef uint8_t mcapi_uint8_t;
typedef uint16_t mcapi_uint16_t;
typedef uint32_t mcapi_uint32_t;
typedef uint64_t mcapi_uint64_t;
typedef uint8_t mcapi_boolean_t;
 
/* mcapi data */
typedef uint32_t mcapi_status_t;
typedef uint32_t mcapi_endpoint_t;
typedef int mcapi_node_t;
typedef int mcapi_port_t;
typedef char mcapi_version_t[20];
typedef int mcapi_priority_t;
typedef int mcapi_timeout_t;
typedef enum {
OTHER_REQUEST,
OPEN_PKTCHAN,
OPEN_SCLCHAN,
SEND,
RECV,
GET_ENDPT
} mcapi_request_type;
 
typedef struct {
mcapi_boolean_t valid;
size_t size;
mcapi_request_type type;
void* buffer;
void** buffer_ptr;
uint32_t node_num;
uint32_t port_num;
mcapi_boolean_t completed;
mcapi_boolean_t cancelled;
mcapi_endpoint_t handle;
mcapi_status_t status;
mcapi_endpoint_t* endpoint;
} mcapi_request_t;
 
 
/* internal handles */
typedef uint32_t mcapi_pktchan_recv_hndl_t;
typedef uint32_t mcapi_pktchan_send_hndl_t;
typedef uint32_t mcapi_sclchan_send_hndl_t;
typedef uint32_t mcapi_sclchan_recv_hndl_t;
 
 
/* enum for channel types */
typedef enum {
MCAPI_NO_CHAN = 0,
MCAPI_PKT_CHAN,
MCAPI_SCL_CHAN,
} channel_type;
 
 
 
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.