/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* perf720 src/perf/perfagent/usr/samples/perfagent/server/SpmiDds.c 1.8  */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* OBJECT CODE ONLY SOURCE MATERIALS                                      */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1992,1993              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/*
 *   COMPONENT_NAME: PERFAGENT
 *
 *   FUNCTIONS: SpmiStopMe
 *		main
 *
 *   ORIGINS: 30
 *
 *
 *   (C) COPYRIGHT International Business Machines Corp. 1992,1993
 *   All Rights Reserved
 *   Licensed Materials - Property of IBM
 *   US Government Users Restricted Rights - Use, duplication or
 *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 *       NOTICE TO USERS OF THE SOURCE CODE EXAMPLES
 *
 * THE SOURCE CODE EXAMPLES PROVIDED BY IBM ARE ONLY INTENDED TO ASSIST IN THE
 * DEVELOPMENT OF A WORKING SOFTWARE PROGRAM.  THE SOURCE CODE EXAMPLES DO NOT
 * FUNCTION AS WRITTEN:  ADDITIONAL CODE IS REQUIRED.  IN ADDITION, THE SOURCE
 * CODE EXAMPLES MAY NOT COMPILE AND/OR BIND SUCCESSFULLY AS WRITTEN.
 * 
 * INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE
 * EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT
 * WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
 * OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS,
 * IS WITH YOU.  SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE
 * DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION
 * DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR
 * CORRECTION.
 * 
 * IBM does not warrant that the contents of the source code examples, whether
 * individually or as one or more groups, will meet your requirements or that
 * the source code examples are error-free.
 * 
 * IBM may make improvements and/or changes in the source code examples at
 * any time.
 * 
 * Changes may be made periodically to the information in the source code
 * examples; these changes may be reported, for the sample device drivers
 * included herein, in new editions of the examples.
 * 
 * References in the source code examples to IBM products, programs, or
 * services do not imply that IBM intends to make these available in all
 * countries in which IBM operates.  Any reference to an IBM licensed
 * program in the source code examples is not intended to state or imply
 * that only IBM's licensed program may be used.  Any functionally equivalent
 * program may be used.
 * 
 * RISC System/6000 is a trademark of International Business Machines
 * Corporation.
 *
 */

static char *Sccs_id = "@(#)16  1.5  src/perf/perfagent/usr/samples/perfagent/server/SpmiDds.c, perfagent, perf411, 9430C411a 7/29/94 17:32:44";

/* EXECUTION NOTES:
 * To invoke from the command line, perform the following command:
 *              > SpmiDds &
 *
 * This program acts as a data supplier.  This program supplies non-volatile
 * and volatile contexts and updates those statistics.
 * This program adds the following statistics and contexts to the list of 
 * available statistics:
 *
 * DDS/Samples/ddsupl1
 * DDS/Samples/ddsupl1/gadgets
 * DDS/Samples/ddsupl1/widgets
 * DDS/Samples/ddsupl1/dds2  
 * DDS/Samples/ddsupl1/dds2/level
 * DDS/Samples/ddsupl1/dds2/queue
 * DDS/Samples/ddsinst
 * DDS/Samples/ddsinst/level 
 * DDS/Samples/ddsinst/queue
 *
 * SpmiPeek could be called so that the statistics and contexts can be verified
 * as being added to the list of available statistics.
 * When finished executing this program, the process must be killed.
 */

#ifdef _AIX
#define CONST const
#else
#define CONST
#endif

#include <stdio.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <sys/Spmidef.h>

extern char    SpmiErrmsg[];
extern int     SpmiErrno;

struct dat
{
   u_long      a;
   u_long      b;
};

struct inst
{
   u_long      a;
   u_long      b;
};

/* statistics to be added */
static CONST struct SpmiRawStat PUStats[] = {
{  "gadgets", "Fake counter value", 0, 100, SiCounter,
   SiLong, 1, SZ_OFF(dat, a, SiULong), NULL},
{  "widgets", "Another Fake counter value", 0, 100, SiCounter,
   SiLong, 2, SZ_OFF(dat, b, SiULong), NULL},
};

/* statistics to be added */
static CONST struct SpmiRawStat InstStats[] = {
{  "level", "Fake quantity value", 0, 100, SiQuantity,
   SiLong, 1, SZ_OFF(inst, a, SiULong), NULL},
{  "queue", "Another fake quantity value", 0, 100, SiQuantity,
   SiLong, 2, SZ_OFF(inst, b, SiULong), NULL},
};

/* non-volatile contexts */
static CONST cx_create cx_table[] = {
   {"DDS/Samples", "Sample Dynamic Data Supplier", 2, 0,
      NULL, 0, NULL, 0, NULL, SiNoInst},
   {"DDS/Samples/ddsupl1", "Bogus Context Number 1", 201, 0,
      (struct SpmiRawStat *)PUStats, STAT_L(PUStats),
		NULL, 0, NULL, SiNoInst},
};

/* volatile contexts */
static CONST cx_create inst_table[] = {
   {"DDS/Samples/ddsinst", "Instantiable Context Number 1", 202, 0,
      (struct SpmiRawStat *)InstStats, STAT_L(InstStats),
		NULL, 0, NULL, SiNoInst},
   {"DDS/Samples/ddsupl1/dds2", "Instantiable SubContext Number 2", 301, 0,
      (struct SpmiRawStat *)InstStats, STAT_L(InstStats),
		NULL, 0, NULL, SiNoInst},
};

static int         CxCount = CX_L(cx_table);  /* Count of contexts defined  */
static int	   InstCount = CX_L(inst_table);
static SpmiShare   *dataarea = NULL;         /* Shared memory pointer      */
static struct dat  *d = NULL;                /* Pointer to stats data area */
static struct inst *pt1 = NULL;              /* pointer to volatile data area */
static struct inst *pt2 = NULL;              /* pointer to volatile data area */

/*============================= SpmiStopMe() =============================*/
/* This function is called to clean up the shared memory and exit the    */
/* interface.                                                            */
/*=======================================================================*/

void SpmiStopMe()
{
   /* Delete any added contexts */
   if (pt1)
   {
      if (SpmiDdsDelCx((char *)pt1))
      {
        printf("ERROR:  SpmiDdsDelCx (pt1) Failed\n");
	if (strlen(SpmiErrmsg))
	    printf("%s", SpmiErrmsg);
      }
      else
        pt1 = NULL;
   }
   if (pt2)
   {
      if (SpmiDdsDelCx((char *)pt2))
      {
        printf("ERROR:  SpmiDdsDelCx (pt2) Failed\n");
	if (strlen(SpmiErrmsg))
	    printf("%s", SpmiErrmsg);
      }
      else
        pt2 = NULL;
   }

   SpmiExit();
   if (SpmiErrno)
   {
      printf("ERROR:  SpmiExit Failed\n");
      if (strlen(SpmiErrmsg))
          printf("%s", SpmiErrmsg);
   }

   exit(0);
}

/*========================================================================*/

int main()
{
   int 	i=2, j=3;

   /* initialize the data supplier */
#ifdef _AIX
   dataarea = SpmiDdsInit((cx_create *)cx_table, CxCount,
					(cx_create *)inst_table, InstCount, "/etc/SpmiDdsSHM");
#else
   dataarea = SpmiDdsInit((cx_create *)cx_table, CxCount,
					(cx_create *)inst_table, InstCount, "/etc/SpmiDdsSHM", 4*1024);
#endif
   if (!dataarea)
   {
           printf("ERROR:  SpmiDdsInit Failed\n");
	   if (strlen(SpmiErrmsg))
               printf("%s", SpmiErrmsg);
           exit(-1);
   }

   d = (struct dat *)&dataarea->SiShArea[0];

   /* interrupt signals */
#ifdef _NO_PROTO
   signal(SIGTERM, (void(*)())SpmiStopMe);
   signal(SIGHUP,  (void(*)())SpmiStopMe);
   signal(SIGINT,  (void(*)())SpmiStopMe);
   signal(SIGSEGV, (void(*)())SpmiStopMe);
#else
   signal(SIGTERM, (void(*)(int))SpmiStopMe);
   signal(SIGHUP,  (void(*)(int))SpmiStopMe);
   signal(SIGINT,  (void(*)(int))SpmiStopMe);
   signal(SIGSEGV, (void(*)(int))SpmiStopMe);
#endif /* _NO_PROTO */

   /* initialize the data statistics */
   gettimeofday(&dataarea->SiShT, NULL);
   d->a = 22;
   d->b = 42;

   while(!dataarea->SiShGoAway)
   {
#ifdef _AIX
      usleep(4990000);
#else
      sleep(5);
#endif
      gettimeofday(&dataarea->SiShT, NULL);
      i *= j;
      if (i > 2000)
	    i = 2;

      /* update non-volatile contexts */
      d->a += i;
      d->b += 42;

      /* Create volatile contexts */
      if(!pt1)
      {
	if (!(pt1 = (struct inst *)SpmiDdsAddCx(0, "DDS/Samples/ddsinst", 
                                               "Dynamically added", 202)))
        {
	    printf("ERROR:  SpmiDdsAddCx (pt1) Failed\n");
	    if (strlen(SpmiErrmsg))
	        printf("%s\n", SpmiErrmsg);
        }
        else
	{
	  	pt1->a = 28;
	  	pt1->b = 62;
        }
      }

      if(!pt2)
      {
	if (!(pt2 = (struct inst *)SpmiDdsAddCx(1, "DDS/Samples/ddsupl1/dds2", 
                                               "Dynamically added 2", 203)))
        {
	    printf("ERROR:  SpmiDdsAddCx (pt2) Failed\n");
	    if (strlen(SpmiErrmsg))
	        printf("%s\n", SpmiErrmsg);
        }
        else
	{
	    pt2->a = 40;
	    pt2->b = 15;
        }
      }

      /* update volatile contexts */
      if (pt1)
      {
	pt1->a += 28;
        pt1->b += 62;
        if (pt1->a > 500)
           pt1->a = 28;
        if (pt1->b > 1000)
           pt1->b = 62;
      }
      if (pt2)
      {
	pt2->a += 28;
        pt2->b += 62;
        if (pt2->a > 500)
           pt2->a = 40;
        if (pt2->b > 1000)
           pt2->b = 15;
      }
   }  /* end while loop */
   SpmiStopMe();
}
