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; } } }