performance/semaphore.c
///////////////////////////////////////////////////////////////////////////////
// Filename: semaphore.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: measure how fast semaphore operations are
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date Time Name Description
// -------- -------- -------- ------------------------------------------------
// 96/03/01 13:49:41 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////
// Feature test switches ///////////////////////////// Feature test switches //
/* NONE */
// System headers /////////////////////////////////////////// System headers //
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
// Local headers ///////////////////////////////////////////// Local headers //
#include "../common.h"
// Macros /////////////////////////////////////////////////////////// Macros //
/* NONE */
// File scope objects /////////////////////////////////// File scope objects //
const int NUMBER_REPEAT = 10000; // how often for measurements
const int SEM_MODE = 0666; // SEM_R | SEM_A; // read and alter
// External variables, functions, and classes ///////////// External objects //
/* NONE */
// Signal catching functions ///////////////////// Signal catching functions //
/* NONE */
// Structures, unions, and class definitions /////////////////// Definitions //
/* NONE */
// Functions and class implementation /// Functions and class implementation //
/* NONE */
// Main /////////////////////////////////////////////////////////////// Main //
int
main(int argc, char *argv[])
{
error.set_program_name(argv[0]);
int i;
// do some performance measurements
// check size
#ifdef linux
if( NUMBER_REPEAT > SEMVMX)
error.panic("SEMVMX too small, reduce NUMBER_REPEAT!");
#endif
// create semaphore
int semid = semget(IPC_PRIVATE, 1, SEM_MODE);
if(semid == -1)
error.system("semget error");
// set to initial value
#ifdef linux
semun initial_value;
#else
union semun {
int val;
struct semid_ds *buf;
ushort *array;
} initial_value;
#endif
initial_value.val = 0;
if( semctl(semid, 0, SETVAL, initial_value) == -1)
error.system("semctl error");
// initialize default values
struct sembuf op;
op.sem_num = 0; // member number (we only have number 0)
op.sem_op = 1; // inc
op.sem_flg = 0; // no flags
measurement mes(argv[0], "mes", 4);
// do measurements without undo
// start timer
mes.start(-1, NUMBER_REPEAT, "Measuring semop() +1 operations without undo");
for(i=0; i < NUMBER_REPEAT; i++)
{
if( semop(semid, &op, 1) == -1)
error.system("semop error");
}
// end timer
mes.end();
// now do the reverse..
op.sem_op = -1; // dec
// start timer
mes.start(-1, NUMBER_REPEAT, "Measuring semop() -1 operations without undo");
for(i=0; i < NUMBER_REPEAT; i++)
{
if( semop(semid, &op, 1) == -1)
error.system("semop error");
}
// end timer
mes.end();
// do measurements with undo
op.sem_op = 1; // inc
op.sem_flg = SEM_UNDO; // remeber change if program crashes or exit()s
// start timer
mes.start(-1, NUMBER_REPEAT, "Measuring semop() +1 operations with undo");
for(i=0; i < NUMBER_REPEAT; i++)
{
if( semop(semid, &op, 1) == -1)
error.system("semop error");
}
// end timer
mes.end();
// now do the reverse..
op.sem_op = -1; // dec
// start timer
mes.start(-1, NUMBER_REPEAT, "Measuring semop() -1 operations with undo");
for(i=0; i < NUMBER_REPEAT; i++)
{
if( semop(semid, &op, 1) == -1)
error.system("semop error");
}
// end timer
mes.end();
// destroy semaphore
#ifdef linux
union semun nop;
#else
int nop=0;
#endif
if(semctl(semid, 0, IPC_RMID, nop) == -1)
error.system("semctl error");
mes.writeout_logfile(false, true, true); // use cout for output
return(EXIT_SUCCESS);
}