C++ example: Integrating user-defined transactions into Collection Services

 

This C++ example program shows how to use the Start Transaction and End Transaction APIs to integrate user-defined transaction performance data into Collection Services.

By using the code examples, you agree to the terms of the Code license and disclaimer information.

//**********************************************************************
// tnstst.C //
// This example program illustrates the use 
// of the Start/End Transaction APIs (qypeStartTransaction,
// qypeEndTransaction). 
// 
//
// This program can be invoked as follows: //   CALL lib/TNSTST PARM('threads' 'types' 'transactions' 'delay')
//     where //       threads      = number of threads to create (10000 max)
//       types        = number of transaction types for each thread //       transactions = number of transactions for each transaction //                      type //       delay        = delay time (millisecs) between starting and //                      ending the transaction //
// This program will create "threads" number of threads. Each thread // will generate transactions in the same way. A thread will do // "transactions" number of transactions for each transaction type,
// where a transaction is defined as a call to Start Transaction API,
// then a delay of  "delay" millisecs, then a call to End Transaction // API. Thus, each thread will do a total of "transactions" * "types" // number of transactions. Each transaction type will be named // "TRANSACTION_TYPE_nnn" where nnn ranges from 001 to "types". For // transaction type n, there will be  n-1 (16 max) user-provided // counters reported, with counter m reporting m counts for each // transaction.
//
// This program must be run in a job that allows multiple threads // (interactive jobs typically do not allow multiple threads). One // way to do this is to invoke the program using the SBMJOB command // specifying ALWMLTTHD(*YES). 
//
//**********************************************************************

#define _MULTI_THREADED 
// Includes #include "pthread.h" #include "stdio.h" #include "stdlib.h" #include "string.h" #include "qusec.h" #include "lbcpynv.h" #include "qypesvpg.h" 
// Constants #define maxThreads 10000 
// Transaction pgm parm structure typedef struct 
{
  int types;   
  int trans;   int delay; } tnsPgmParm_t; 
// Error code structure typedef struct {
  Qus_EC_t error;   char     Exception_Data[100]; } error_code_t; 

//**********************************************************************
//
// Transaction program to run in each secondary thread // 
//**********************************************************************

void *tnsPgm(void *parm)
{ 
  tnsPgmParm_t *p = (tnsPgmParm_t *)parm; 
  char tnsTyp[] = "TRANSACTION_TYPE_XXX";   char pexData[] = "PEX";   unsigned int pexDataL = sizeof(pexData) - 1;   unsigned long long colSrvData[16] = {1,2,3,4,5,6,7,8,
                                       9,10,11,12,13,14,15,16};   unsigned int colSrvDataL;   char tnsStrTim[8]; 
  struct timespec ts = {0, 0};   
  error_code_t errCode; 
  _DPA_Template_T target, source; // Used for LBCPYNV MI instr 
  unsigned int typCnt;   unsigned int tnsCnt;   int rc; 

  // Initialize error code   memset(&errCode, 0, sizeof(errCode));   errCode.error.Bytes_Provided = sizeof(errCode); 
  // Initialize delay time   ts.tv_sec  = p->delay / 1000;   ts.tv_nsec = (p->delay % 1000) * 1000000; 
  // Loop doing transactions   
  for (tnsCnt = 1; tnsCnt <= p->trans; tnsCnt++)
  {
    for (typCnt = 1; typCnt <= p->types; typCnt++)
    {
      // Set number field in transaction type 
      source.Type = _T_UNSIGNED;       source.Length = 4;       source.reserved = 0;       target.Type = _T_ZONED;       target.Length = 3;       target.reserved = 0;       _LBCPYNV(tnsTyp + 17, &target, &typCnt, &source); 
      // Set Coll Svcs data length in bytes       colSrvDataL = (typCnt <= 16) ? (typCnt - 1) : 16;       colSrvDataL = colSrvDataL * 8; 
      // Call Start Transaction API       qypeStartTransaction(tnsTyp,
                           (unsigned int *)&tnsCnt,
                           pexData,
                           (unsigned int *)&pexDataL,
                           tnsStrTim,
                           &errCode); 
      // Delay specified amount       rc = pthread_delay_np(&ts);             
      // Call End Transaction API       qypeEndTransaction(tnsTyp,
                         (unsigned int *)&tnsCnt,
                         pexData,
                         (unsigned int *)&pexDataL,
                         tnsStrTim,
                         (unsigned long long *)&colSrvData[0],
                         (unsigned int *)&colSrvDataL,
                         &errCode);     }
  }

  return NULL; }


//**********************************************************************
//
// Main program to run in primary thread // 
//**********************************************************************

void main(int argc, char *argv[])
{
  // Integer version of parms   int threads;  // # of threads   int types;    // # of types   int trans;    // # of transactions   int delay;    // Delay in millisecs 
  pthread_t threadHandle[maxThreads];   tnsPgmParm_t tnsPgmParm;   int rc; 
  int i; 

  // Verify 4 parms passed  
  if (argc != 5)
  {
    printf("Did not pass 4 parms\n");     return;   }

  // Copy parms into integer variables 
  threads = atoi(argv[1]);   types   = atoi(argv[2]);   trans   = atoi(argv[3]);   delay   = atoi(argv[4]); 
  // Verify parms   if (threads > maxThreads)
  {
    printf("Too many threads requested\n");     return;   }

  // Initialize transaction pgm parms (do not modify   // these while threads are running)  
  tnsPgmParm.types = types;   tnsPgmParm.trans = trans;   tnsPgmParm.delay = delay; 
  // Create threads that will run transaction pgm   for (i=0; i < threads; i++)
  {
    // Clear thread handle     memset(&threadHandle[i], 0, sizeof(pthread_t));     // Create thread 
    rc = pthread_create(&threadHandle[i],      // Thread handle                         NULL,                  // Default attributes                         tnsPgm,                // Start routine                         (void *)&tnsPgmParm);  // Start routine parms     if (rc != 0)
      printf("pthread_create() failed, rc = %d\n", rc);   }

  // Wait for each thread to terminate   for (i=0; i < threads; i++)
  {
    rc=pthread_join(threadHandle[i],  // Thread handle                     NULL);            // No exit status   }

}  /* end of Main */

 

Parent topic:

User-defined transactions