System aspects

This chapter address some generic aspects of the SISCI API related to the initialization of the SISCI program environment and to the retrieval of information about the underlying interconnect system.

In particular, you will learn:

  • How to initialize the SISCI API library.

  • How to manage the so-called “virtual devices”.

  • How to get useful information about the underlying network system.

  • How to check if a remote node is on-line.

Initializing the SISCI environment

Before calling any other function in the SISCI API one should initialize the library calling SCIInitialize():

sci_error_t error;

SCIInitialize(NO_FLAGS, &error);
if (error == SCI_ERR_OK) {
    /* successful initialization */
} else {
    /* manage error */
}

/* go on with the program */

If SCIInitialize() fails, there is something fundamentally wrong with the local software or hardware installation. One typical problem is that the SISCI API library and driver versions are not consistent, in which case the error is SCI_ERR_INCONSISTENT_VERSIONS.

Before exiting, but after any SISCI API call, the program should call SCITerminate() to properly release all SISCI resources:

/* no SISCI API calls here */
SCIInitialize(...);

/* SISCI program functionality goes here */

SCITerminate();

/* no SISCI API calls here */

Both SCIInitialize()and SCITerminate()should only be called once in your program, independently of how many SISCI resources you use.

Virtual device handles

Most SISCI API functionality is managed through virtual device handles. A virtual device handle can be seen as a communication channel with the underlying SISCI driver.

Note

Each virtual device can only hold one of each resource. E.g., you would need two virtual devices to manage two segments, but only one virtual device to manage one interrupt and one segment.

A virtual device is created with SCIOpen()and removed with SCIClose():

sci_desc_t v_dev;
sci_error_t error;

SCIInitialize(...);

SCIOpen(&v_dev, NO_FLAGS, &error);
if (error != SCI_ERR_OK) {
    /* manage error */
}

/* use v_dev */

SCIClose(v_dev, NO_FLAGS, &error);
if (error != SCI_ERR_OK) {
    /* manage error */
}

SCITerminate();

A typical error in case of failure of SCIOpen()is SCI_ERR_NOT_INITIALIZED, which means that you forgot to call SCIInitialize() before SCIOpen().

Querying information

The SISCI API provides a way to retrieve some information about the underlying interconnect system. In particular, you can retrieve information about the vendor identifier, the version of the API implemented, and some adapter characteristics. Other information, both general and vendor-dependent, can also be provided. Refer to the SISCI API specification for further query options.

The function used to query the above mentioned information is SCIQuery(). This function has a query command as input and returns the requested information. Additional input information, like subcommands, is passed in the same data structure used for the output. The following two sections show how to get the API version and the node identifier associated with a certain adapter. The procedure to access other information is similar; please refer to the SISCI API specification for the details.

Determining the SISCI API version

The SCIQuery() call is in this case quite simple. The first parameter specifies the query type, which in this case is SCI_Q_API. Results are stored in the sci_query_string structure, referenced in the second parameter. This structure contains a pointer to an already allocated character array and an integer representing the size of the array.

const unsigned int QUERY_STRING_LENGTH = 64;
char api_version[QUERY_STRING_LENGTH];

sci_query_string_t query;
sci_error_t error;
query.str = api_version;
query.length = QUERY_STRING_LENGTH;

SCIQuery(SCI_Q_API, &query, NO_FLAGS, &error);

if (error == SCI_ERR_OK) {
    /* api_version contains the requested value */
} else {
    /* manage error */
}

Determining the node identifier of a certain adapter

SCIQuery()requires additional parameters to get the proper information for a certain adapter: a subcommand specifying the query type and the adapter identifier. The additional information is passed through the sci_query_adapter structure, which also contains an integer field for the output.

unsigned int local_node_id;
sci_query_adapter_t query;
sci_error_t error;
query.subcommand = SCI_Q_ADAPTER_NODE_ID;
query.localAdapterNo = ADAPTER_NO;
query.data = &local_node_id;

SCIQuery(SCI_Q_ADAPTER, &query, NO_FLAGS, &error);
if (error == SCI_ERR_OK) {
    /* local_node_id contains the requested value */
} else {
    /* manage error */
}

Probing a remote node

The SISCI API function SCIProbeNode() can be used to check if communication is possible to a certain remote node through a certain local adapter:

sci_desc_t v_dev;
sci_error_t error;
int reachable;

SCIInitialize(...);
SCIOpen(&v_dev, ...);

reachable = SCIProbeNode(v_dev, ADAPTER_NO, REMOTE_NODE_ID, NO_FLAGS, &error);
if (reachable == 1) {
    /* node is reachable */
} else { /* error != SCI_ERR_OK */
    /* manage the error */
}

If the function fails, typical errors are:

SCI_ERR_NO_LINK_ACCESS

There are problems with the local adapter or cable.

SCI_ERR_NODE_NOT_RESPONDING

There are problems with the remote adapter.

SCI_ERR_NO_SUCH_NODEID

There is no reachable node with the specified identifier on the network accessible through the specified adapter.