编程接口指南

RSMAPI 用法示例

本节提供了一个简单程序来说明 RSMAPI 的用法。此程序在两个节点上运行:导出者节点和导入者节点。导出者节点用于创建和发布内存段,然后等待将消息写入段。导入者节点用于连接到导出的段,写入消息,然后通知导出者。

/*

 * Copyright (c) 1998 by Sun Microsystems, Inc.

 * All rights reserved.

 */

#include <stdio.h>

#include <rsm/rsmpai.h>

#include <errno.h>





/*

        To run this program do the following:



        First node(assuming node id = 1):

                rsmtest -e -n 2



        Second node(assuming node id = 2):

                rsmtest -i -n 1



       The program will prompt the importer for a message at the 

       console. Enter any message and hit return. The message will 

       be displayed on the export console.

*/



typedef struct {

        char    out;

        char    in;

        char    data[1];

}msg_t;



#define SEG_ID 0x400000

#define EXPORT  0

#define IMPORT  1



#define BUFSIZE (1024 * 8)

#define DEFAULT_SEGSZ BUFSIZE



#define RSM_PERM_READ                       0400

#define RSM_PERM_WRITE                      0200

#define RSM_PERM_RDWR                       (RSM_PERM_READ|RSM_PERM_WRITE)

#define

RSM_ACCESS_TRUSTED





0666



rsm_topology_t *tp;



int iterations = 10;



int mode = EXPORT;

int test = 0;



char *buf;

int buflen = BUFSIZE;

int offset = 0;

volatile char *iva;



int status;

rsm_memseg_id_t segid;

rsmapi_controller_handle_t ctrl;

rsmapi_controller_attr_t attr;

rsm_memseg_export_handle_t seg;

rsm_memseg_import_handle_t imseg;

rsm_access_entry_t list[2];

rsm_node_id_t dest;



extern void *valloc(size_t);

extern void exit();

extern void sleep();

extern int atoi(const char *);



/* The following function exports a segment and publishes it.

 */

static int

export()

{

        int i;



        /* allocate and clear memory */

        buf = (char *)valloc(buflen);



        

if (!buf) {

               



(void) fprintf(stderr, "Unable to allocate memory\n");

               



exit (1);

        

}

        for (i = 0; i < buflen; i++)

                buf[i] = 0;



        

/* Create an export memory segment */

        status = rsm_memseg_export_create(ctrl, &seg, (void *)buf, buflen);

        if (status != 0) {

                (void) fprintf(stderr,

                      "unable to create an exported segment %d\n", status);

                exit(1);

        }



        /* Set up access list for publishing to nodes 1 and 2 */

        list[0].ae_node = tp->topology_hdr.local_nodeid ;

        

/* Allow read and write permissions */

        list[0].ae_permission = RSM_ACCESS_TRUSTED;

        list[1].ae_node = tp->topology_hdr.local_nodeid + 1;

        

/* Allow read and write permissions */

        list[1].ae_permission = RSM_ACCESS_TRUSTED;  



        

/* Publish the created export segment */ 

        status = rsm_memseg_export_publish(seg, &segid, list, 0);

        if (status != 0) {

              (void) fprintf(stderr, "unable to pub segment %d\n", status);

              exit(1);

        }

        return (0);

}



/* The following function is used to connect to an exported memory segment.

 */

static void

import()

{

        /* Connect to exported segment and set up mapping for

         * access through local virtual addresses.

         */

again:

        status = rsm_memseg_import_connect(ctrl, dest, segid, RSM_PERM_RDWR,

            &imseg);

        if (status != 0) {

                (void) fprintf(stderr,

                                "unable to conect to segment %x err %x\n",

                                segid, status);

                sleep(1);

                goto again;

        }



        iva = NULL;

        status = rsm_memseg_import_map(imseg, (void **)&iva,

                                  RSM_MAP_NONE, RSM_PERM_RDWR, 0, buflen);

        if (status != 0) {

             (void) fprintf(stderr, "unable to mmap segment %d\n", status);

             exit(1);

        }

}



/* Unpublish and destroy the export segment */

static void

export_close()

{

again:

        status = rsm_memseg_export_unpublish(seg);

        if (status != 0) {

                (void) fprintf(stderr,

                        "unable to create an unpub segment %d\n", status);

                sleep(10);

                goto again;

        }



        status = rsm_memseg_export_destroy(seg);

        if (status != 0) {

                (void) fprintf(stderr, "unable to destroy segment %d\n",

                                status);

                exit(1);

        }

}



/* Unmap the virtual address mapping and disconnect the segment */

static void

import_close()

{

        status = rsm_memseg_import_unmap(imseg);

        if (status != 0) {

            (void) fprintf(stderr, "unable to unmap segment %d\n", status);





                exit(1);

        }



        status = rsm_memseg_import_disconnect(imseg);

        if (status != 0) {

                (void) fprintf(stderr,

                        "unable to disconnect segment %d\n", status);

                exit(1);

        }

}





static void

test0()

{

        volatile msg_t  *mbuf;

        /* Barrier to report error */

        rsmapi_barrier_t bar;

        int i;



        if (mode == EXPORT) {

                (void) export();

                mbuf = (msg_t *)(buf + offset);

                mbuf->in = mbuf->out = 0;

        } else {

             import();

             mbuf = (msg_t *)(iva + offset);

             rsm_memseg_import_init_barrier(imseg, RSM_BARRIER_NODE, &bar);

        }

        

        (void) printf("Mbuf is %x\n", (uint_t)mbuf);

        while (iterations-- > 0) {





int e;



                switch (mode) {

                case EXPORT:

                    while (mbuf->out == mbuf->in) {

                            (void) rsm_intr_signal_wait(seg, 1000);

                    }

                    (void) printf("msg [0x%x %d %d] ",

                            (uint_t)mbuf, (int)mbuf->out, mbuf->in);

                    for (i = 0; mbuf->data[i] != '\0' && i < buflen; i++) {

                            (void) putchar(mbuf->data[i]);

                            mbuf->data[i] = '?';

                    }

                    (void) putchar('\n');



                    mbuf->out++;

                    break;

                case IMPORT:

                    (void) printf("Enter msg [0x%x %d]: ",

                                    (uint_t)mbuf, mbuf->out, mbuf->in);

retry:

                    e = rsm_memseg_import_open_barrier(&bar);

                    if (e != 0) {

                        (void) printf("Barrier open failed %x\n", e);

                        exit(1);

                    }

                    for (i = 0; (mbuf->data[i] = getchar()) != '\n'; i++)

                            ;

                    mbuf->data[i] = '\0';

                    rsm_memseg_import_order_barrier(&bar);

                    mbuf->in++;



                    e = rsm_memseg_import_close_barrier(&bar);

                    if (e != 0) {

                        (void) printf("Barrier close failed, %d\n", e);

                        goto retry;

                    }



                        





(void)rsm_intr_signal_post(imseg);

                        break;

                }

        }



        if (mode == IMPORT) {

                import_close();

        } else {

                export_close();

        }

}





void

main(int argc, char *argv[])

{

        int unit = 0;

        char *device = "sci0";

        int i;



        segid = SEG_ID;

        buflen = DEFAULT_SEGSZ;

        while ((i = getopt(argc, argv, "OCGeid:b:sl:n:k:t:c:u:v")) != -1) {

                switch (i) {

                case 'e':

                        mode = EXPORT;

                        break;

                case 'i':

                        mode = IMPORT;

                        break;

                case 'n':

                        dest = atoi(optarg);

                        if ((int)dest < 0) dest = 0;

                        break;

                default:

                      





  (void) fprintf(stderr, "Usage: %s -ei  -n dest\n",

                                            









 argv[0]);

                      





  exit(1);

                }

        }



        status = rsm_get_controller(device, &ctrl);

        if (status != 0) {

                (void) fprintf(stderr, "Unable to get controller\n");

                exit(1);

        }



        status = rsm_get_controller_attr(ctrl, &attr);

        

       

status = rsm_get_interconnect_topology(&tp);

       

if (status != 0) {

                



(void) fprintf(stderr, "Unable to get topology\n");

                



exit(1);

      

} else {

           

    (void) printf("Local node id = %d\n", 

             





  tp->topology_hdr.local_nodeid);

      

}



       

if (dest == 0) {

              



  dest = tp->topology_hdr.local_nodeid;

                



(void) printf("Dest is adjusted to %d\n", dest);

       

}

   

        switch (test) {

        case 0:

                test0();

                break;

        default:

                (void) printf("No test executed\n");

                break;

        }

}