Dieses Beispiel befindet sich in der Bibliothek SYSLIB.SM2.<ver>. Es verdeutlicht den Gebrauch der Makros SM2GMS und SM2GDAT. Das Beispielprogramm gibt zu Beginn den Hostnamen aus und besorgt das SM2-Online-Messintervall. Anschließend werden im Zyklus des SM2-Online-Messintervalls Daten der SM2-Datenpuffer BASIC, SDEVICE, TIME-IO und DAB ausgegeben. Jeder dieser Datenpuffer dient als Beispiel für einen der vier Datenpuffer-Typen:
BASIC-Datenpuffer (Typ 1)
Der Zeitstempel des Messintervalls wird ausgegeben und die Anzahl der Stichproben des Intervalls wird geholt.SDEVICE-Datenpuffer (Typ 2)
Für jedes Gerät, dessen Auslastung bezüglich DMS-Ein-/Ausgaben einen Schwellwert überschreitet, wird diese Auslastung ausgegeben.TIME-IO-Datenpuffer (Typ 3)
Die Anzahl der aktiven logischen Maschinen wird ausgegeben. Für jede aktive logische Maschine wird die CPU-Auslastung ausgegeben, wenn sie einen Schwellwert überschreitet.DAB-Datenpuffer (Typ 4)
Für jeden DAB-Puffer werden die Anzahl Reads und die Anzahl Read Hits ausgegeben.
Zu beachten ist, dass im Beispiel SM2GDAT das erste Mal mit dem Wert 0 für den Parameter „length_buffer“ aufgerufen wird, um die tatsächlich benötigte Größe von „length_buffer“ festzustellen.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "FHDR.H"
#include "SM2GMS.H"
#include "SM2GDAT.H"
#include "SM2RC.H"
#define SHORT_TIME 1
#define LONG_TIME 60
#define WAIT_SHORT_AND_TRY_AGAIN 0
#define WAIT_LONG_AND_TRY_AGAIN 1
#define BUFFER_TOO_SHORT 2
#define TERMINATE_PROGRAM 3
#define NOT_DEFINED 0
#define NOT_SET 0
#define SET 1
#define SIZE_4K_PAGE 4096
#define DMS_IOS_THRESHOLD_VALUE 60.0
#define CPU_UTILIZATION_THRESHOLD_VALUE 50.0
typedef struct SM2GDAT_buffer_header_mdl StrBufferHeader;
typedef struct SM2GDAT_basic_single_mdl StrBASICsingle;
typedef struct SM2GDAT_sdevice_multiple_mdl StrSDEVICEmultiple;
typedef struct SM2GDAT_time_io_single_mdl StrTIME_IOsingle;
typedef struct SM2GDAT_time_io_multiple_mdl StrTIME_IOmultiple;
typedef struct SM2GDAT_dab_single_mdl StrDABsingle;
typedef struct SM2GDAT_dab_buffer_area_mdl StrDAB_BUFFER_AREAmultiple;
typedef struct SM2GDAT_dab_partial_area_mdl StrDAB_PARTIAL_AREAmultiple;
typedef unsigned char Uchar;
struct SM2GMS_get_measurement_stat_mdl SM2_STATUS;
struct SM2GDAT_get_data_mdl SM2_DATA;
struct SM2GDAT_global_header_mdl *GlobalHeader_ptr;
struct StrBufferHeader *BufferHeader_ptr;
void *buffer_ptr;
long length_buffer = 0L; /* initialized with 0L for the first call of SM2GDAT */
int Cycle;
int NumberSamples;
char DABData;
char LocalHostName[] = " ";
void TerminateProgram( char * );
void main( void )
{
void GetSM2StatusInformations( void );
void CallSM2GDAT( double );
void ShowBASICData( void );
void ShowSDEVICEData( void );
void ShowTIME_IOData( void );
void ShowDABData( void );
GetSM2StatusInformations( );
for( ; ; )
{
CallSM2GDAT( SM2GDAT_BUFFER_BASIC /* data buffer of type 1 */
+ SM2GDAT_BUFFER_SDEVICE /* data buffer of type 2 */
+ SM2GDAT_BUFFER_TIME_IO /* data buffer of type 3 */
+ SM2GDAT_BUFFER_DAB ); /* data buffer of type 4 */
ShowBASICData( );
ShowSDEVICEData( );
ShowTIME_IOData( );
ShowDABData( );
sleep( Cycle );
}
exit( 0 );
}
void TerminateProgram( char *Message )
{
printf( "\n\n%s\n\n", Message );
printf( "Program abnormally terminated.\n" );
exit( -1 );
}
void GetSM2StatusInformations( void )
{
char TRY_AGAIN;
char Message[100];
int Errorhandling( int, int, char * );
TRY_AGAIN = 'y';
while( TRY_AGAIN == 'y' )
{
SM2GMS( SM2_STATUS, LocalHostName ); /* calling macro SM2GMS */
if( SM2_STATUS.hdr.FHDR_RC_MAINCODE == FHDRsuccessful_processing )
TRY_AGAIN = 'n';
else
{
switch( Errorhandling( ( int )SM2_STATUS.hdr.FHDR_RC_MAINCODE,
( int )SM2_STATUS.hdr.FHDR_RC_SUBCODE1,
Message ) )
{
case WAIT_SHORT_AND_TRY_AGAIN:
sleep( SHORT_TIME );
TRY_AGAIN = 'y';
break;
case WAIT_LONG_AND_TRY_AGAIN:
sleep( LONG_TIME );
TRY_AGAIN = 'y';
break;
case TERMINATE_PROGRAM:
TerminateProgram( Message );
break;
default:
TerminateProgram( "Unexpected return code from SM2GMS.\n" );
break;
}
}
}
printf( "Host: %8.8s\n", SM2_STATUS.status.endsystem_name );
if( SM2_STATUS.status.online_cycle == NOT_DEFINED )
Cycle = SM2_STATUS.status.offline_cycle;
else
Cycle = SM2_STATUS.status.online_cycle;
if( SM2_STATUS.status.active_programs.flag.dab == SET )
DABData = 'y'; /* measurement program DAB is active */
else
DABData = 'n'; /* measurement program DAB is not active */
}
void CallSM2GDAT( double BufferSelection )
{
char Message[100];
int Errorhandling( int, int, char * );
void GetMemory( void );
char TRY_AGAIN;
TRY_AGAIN = 'y';
while( TRY_AGAIN == 'y' )
{
/* calling macro SM2GDAT to get the data buffers */
SM2GDAT( SM2_DATA, length_buffer, buffer_ptr, BufferSelection, LocalHostName );
if( SM2_DATA.hdr.FHDR_RC_MAINCODE == FHDRsuccessful_processing )
TRY_AGAIN = 'n';
else
{
switch( Errorhandling( ( int )SM2_DATA.hdr.FHDR_RC_MAINCODE,
( int )SM2_DATA.hdr.FHDR_RC_SUBCODE1,
Message ) )
{
case WAIT_SHORT_AND_TRY_AGAIN:
sleep( SHORT_TIME );
TRY_AGAIN = 'y';
break;
case WAIT_LONG_AND_TRY_AGAIN:
sleep( LONG_TIME );
TRY_AGAIN = 'y';
break;
case BUFFER_TOO_SHORT:
/* needed buffer_length has increased since the last call of SM2GDAT */
/* this return code is especially expected for the first call of */
/* SM2GDAT, because length_buffer is initialized with 0 */
length_buffer = SM2_DATA.length_buffer; /* copy the needed size */
GetMemory( ); /* allocate memory for the output area */
TRY_AGAIN = 'y';
break;
case TERMINATE_PROGRAM:
TerminateProgram( Message );
break;
default:
TerminateProgram( "Unexpected return code from SM2GDAT.\n" );
break;
}
}
}
/* initialize pointer to evaluate the global header */
GlobalHeader_ptr = ( struct SM2GDAT_global_header_mdl * )buffer_ptr;
}
int Errorhandling( int MAINCODE, int SUBCODE1, char *Message )
{
switch( MAINCODE )
{
case FHDRlinkage_error:
switch( SUBCODE1 )
{
case FHDRfct_not_supported:
case FHDRfct_not_available:
case FHDRver_not_supported:
case FHDRalignment_error:
case FHDRss_not_created:
break;
case FHDRwait_short_term:
return( WAIT_SHORT_AND_TRY_AGAIN );
case FHDRwait_long_term:
return( WAIT_LONG_AND_TRY_AGAIN );
default:
break;
}
break;
case SM2RCbuffer_too_short:
return( BUFFER_TOO_SHORT );
case SM2RCno_data:
return( WAIT_SHORT_AND_TRY_AGAIN );
case SM2RCbuffer_not_valid:
case SM2RCsystem_error:
case SM2RCgatherer_down:
break;
default:
break;
}
sprintf( Message, "MAINCODE: %d, SUBCODE1: %d",
MAINCODE, SUBCODE1 );
return( TERMINATE_PROGRAM );
}
void GetMemory( void )
{
static char FirstCall = 'y';
if( FirstCall == 'y' )
FirstCall = 'n';
else
free( buffer_ptr );
buffer_ptr = ( Uchar *)malloc((unsigned int)( SIZE_4K_PAGE * length_buffer ));
if( buffer_ptr == NULL )
TerminateProgram( "malloc( ): Not enough memory." );
}
/*
* evaluates the BASIC data buffer - this is an example to evaluate
* a data buffer of type 1
*/
void ShowBASICData( void )
{
StrBufferHeader *BufferHeader_ptr;
StrBASICsingle *BASICsingle_ptr;
/* initialize pointer to evaluate the buffer header of the BASIC data buffer */
BufferHeader_ptr = ( StrBufferHeader * )GlobalHeader_ptr->basic_ptr;
if( BufferHeader_ptr->state.valid == NOT_SET ) /* no valid data in data buffer */
{
printf( "Data in BASIC-Buffer not valid.\n" );
return;
}
/* initialize pointer to evaluate the fixed data area of the BASIC data buffer */
BASICsingle_ptr =
( StrBASICsingle * ) ( ( Uchar * ) BufferHeader_ptr + BufferHeader_ptr->fixed_part_dsp );
printf( "\n\nTime stamp of cycle: %10.10s %8.8s\n",
BASICsingle_ptr->date, BASICsingle_ptr->time );
NumberSamples = BASICsingle_ptr->samples;
}
/*
* evaluates the SDEVICE data buffer - this is an example to evaluate
* a data buffer of type 2
*/
void ShowSDEVICEData( void )
{
StrBufferHeader *BufferHeader_ptr;
StrSDEVICEmultiple *SDEVICEmultiple_ptr;
Uchar *Multiple_ptr;
int LengthMultipleGroup;
int NumberMultipleGroups;
float DmsBusy;
int i;
/* initialize pointer to evaluate the buffer header of the SDEVICE data buffer */
BufferHeader_ptr = ( StrBufferHeader * )GlobalHeader_ptr->sdevice_ptr;
if( BufferHeader_ptr->state.valid == NOT_SET ) /* no valid data in data buffer */
{
printf( "\nData in SDEVICE-Buffer not valid.\n" );
return;
}
LengthMultipleGroup = BufferHeader_ptr->length_group;
NumberMultipleGroups = BufferHeader_ptr->number_groups;
/* initialize pointer with the address of the first repeat group */
Multiple_ptr = ( Uchar * ) BufferHeader_ptr + BufferHeader_ptr->first_group_dsp;
printf( "\n" );
for( i = 0; i != NumberMultipleGroups; i++, Multiple_ptr += LengthMultipleGroup )
{
/* initialize pointer to evaluate the repeat group of the SDEVICE data buffer */
SDEVICEmultiple_ptr = ( StrSDEVICEmultiple * ) Multiple_ptr;
DmsBusy = ( SDEVICEmultiple_ptr->busy_dms * 100.0 ) / NumberSamples;
if( DmsBusy >= DMS_IOS_THRESHOLD_VALUE )
printf( "Utilization of VSN %6.6s, MN %4.4s, Type %02x: %f\n",
SDEVICEmultiple_ptr->vsn,
SDEVICEmultiple_ptr->mnemonic,
SDEVICEmultiple_ptr->type[1],
DmsBusy );
}
}
/*
* evaluates the TIME_IO data buffer - this is an example to evaluate
* a data buffer of type 3
*/
void ShowTIME_IOData( void )
{
StrBufferHeader *BufferHeader_ptr;
StrTIME_IOsingle *TIME_IOsingle_ptr;
StrTIME_IOmultiple *TIME_IOmultiple_ptr;
Uchar *Multiple_ptr;
int LengthMultipleGroup;
int NumberMultipleGroups;
float SUM, CPU_Utilization;
int i;
/* initialize pointer to evaluate the buffer header of the TIME_IO data buffer */
BufferHeader_ptr = ( StrBufferHeader * )GlobalHeader_ptr->time_io_ptr;
if( BufferHeader_ptr->state.valid == NOT_SET ) /* no valid data in data buffer */
{
printf( "\nData in TIME_IO-Buffer not valid.\n" );
return;
}
/* initialize pointer to evaluate the fixed data area of the TIME_IO data buffer */
TIME_IOsingle_ptr = ( StrTIME_IOsingle * ) ( ( Uchar * ) BufferHeader_ptr
+ BufferHeader_ptr->fixed_part_dsp );
printf( "\nNumber active logical machines: %d\n",
TIME_IOsingle_ptr->active_lm );
LengthMultipleGroup = BufferHeader_ptr->length_group;
NumberMultipleGroups = BufferHeader_ptr->number_groups;
/* initialize pointer with the address of the first repeat group */
Multiple_ptr = ( Uchar * ) BufferHeader_ptr + BufferHeader_ptr->first_group_dsp;
for( i = 0; i != NumberMultipleGroups; i++, Multiple_ptr += LengthMultipleGroup )
{
/* initialize pointer to evaluate the repeat group of the TIME_IO data buffer */
TIME_IOmultiple_ptr = ( StrTIME_IOmultiple * ) Multiple_ptr;
SUM = ( TIME_IOmultiple_ptr->tu_time
+ TIME_IOmultiple_ptr->tpr_time
+ TIME_IOmultiple_ptr->sih_time );
if( ( SUM + TIME_IOmultiple_ptr->idle_time ) > 0 )
CPU_Utilization = ( SUM * 100.0 ) / ( SUM + TIME_IOmultiple_ptr->idle_time );
else
CPU_Utilization = 0.0;
if( i == 0 )
{
/* the first repeat group contains the average values of all logical machines */
printf( "Average CPU utilization of all logical machines: %f %%\n",
CPU_Utilization );
}
else
{
if( CPU_Utilization >= CPU_UTILIZATION_THRESHOLD_VALUE )
printf( "CPU utilization logical machine %d: %f %%\n",
i, CPU_Utilization );
}
}
}
/*
* evaluates the DAB data buffer - this is an example to evaluate
* a data buffer of type 4
*/
void ShowDABData( void )
{
StrBufferHeader *BufferHeader_ptr;
StrDABsingle *DABsingle_ptr;
StrDAB_BUFFER_AREAmultiple *DAB_BUFFER_AREAmultiple_ptr;
Uchar *Multiple_ptr;
int LengthMultipleGroup;
int NumberMultipleGroups;
long reads, read_hits;
int i;
void EvaluatePartialAreas( int, StrDABsingle *, long *, long *);
if( DABData == 'n' )
{
printf( "\nMeasurement program DAB is not active.\n" );
return;
}
/* initialize pointer to evaluate the buffer header of the DAB data buffer */
BufferHeader_ptr = ( StrBufferHeader * )GlobalHeader_ptr->dab_ptr;
if( BufferHeader_ptr->state.valid == NOT_SET ) /* no valid data in data buffer */
{
printf( "\nData in DAB-Buffer not valid.\n" );
return;
}
/* initialize pointer to evaluate the fixed data area of the DAB data buffer */
DABsingle_ptr =
( StrDABsingle * ) ( ( Uchar * ) BufferHeader_ptr + BufferHeader_ptr->fixed_part_dsp );
if( DABsingle_ptr->reconfigurations != 0 ) /* DAB reconfiguration */
{
printf( "\nDAB reconfiguration in last cycle.\n" );
return;
}
LengthMultipleGroup = DABsingle_ptr->length_buffer_area_group;
NumberMultipleGroups = DABsingle_ptr->number_buffer_area_groups;
/* initialize pointer with the address of the first buffer area repeat group */
Multiple_ptr = ( Uchar * ) DABsingle_ptr + DABsingle_ptr->first_buffer_area_group_dsp;
printf( "\n" );
for( i = 0; i != NumberMultipleGroups; i++, Multiple_ptr += LengthMultipleGroup )
{
reads = read_hits = 0L;
/* initialize pointer to evaluate the buffer area repeat group of the DAB data buffer */
DAB_BUFFER_AREAmultiple_ptr = ( StrDAB_BUFFER_AREAmultiple * ) Multiple_ptr;
EvaluatePartialAreas( i + 1, DABsingle_ptr, &reads, &read_hits );
printf( "DAB buffer %-32.32s: reads: %ld, read_hits: %ld\n",
DAB_BUFFER_AREAmultiple_ptr->id, reads, read_hits );
}
}
void EvaluatePartialAreas( int BufferIndex, StrDABsingle *DABsingle_ptr,
long *reads, long *read_hits )
{
StrDAB_PARTIAL_AREAmultiple *DAB_PARTIAL_AREAmultiple_ptr;
Uchar *Multiple_ptr;
int LengthMultipleGroup;
int NumberMultipleGroups;
int i;
LengthMultipleGroup = DABsingle_ptr->length_partial_area_group;
NumberMultipleGroups = DABsingle_ptr->number_partial_area_groups;
/* initialize pointer with the address of the first partial area repeat group */
Multiple_ptr = ( Uchar * ) DABsingle_ptr + DABsingle_ptr->first_partial_area_group_dsp;
for( i = 0; i != NumberMultipleGroups; i++, Multiple_ptr += LengthMultipleGroup )
{
/* initialize pointer to evaluate the buffer area repeat group of the DAB data buffer */
DAB_PARTIAL_AREAmultiple_ptr = ( StrDAB_PARTIAL_AREAmultiple * ) Multiple_ptr;
/* the partial area belongs to the buffer and was served in the monitoring cycle */
if( DAB_PARTIAL_AREAmultiple_ptr->buffer_index == BufferIndex
&& DAB_PARTIAL_AREAmultiple_ptr->state == SM2GDATserved )
{
*reads += DAB_PARTIAL_AREAmultiple_ptr->transfers.read;
*read_hits += DAB_PARTIAL_AREAmultiple_ptr->transfers.read_hit;
}
}
}