performance/message.c
///////////////////////////////////////////////////////////////////////////////
// Filename: message.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: measure how long it takes to send/receive SYSV IPC messages
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date Time Name Description
// -------- -------- -------- ------------------------------------------------
// 96/03/02 02:30:17 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/msg.h>
#include <unistd.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
#ifndef MSGMAX
#define MSGMAX 2048
#endif
const int size_max = MSGMAX; // maximum size of messages
const int MSG_MODE = 0666; // MSG_R | MSG_W; // read and write
const int measure_max = 32; // maximum number of measurements
// 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( size_max > MSGMAX)
error.panic("MSGMAX too small, reduce size_max!");
#endif
// create message queue
int msgid = msgget(IPC_PRIVATE, MSG_MODE);
if(msgid == -1)
error.system("msgget error");
synchronization_init();
// get buffer which we can work
struct msgbuf *buffer = (struct msgbuf *)malloc(size_max+4);
// +4 for long at beginning of buffer
if(!buffer)
error.panic("out of memory");
// set type (priority)
buffer->mtype = 1; // has to be positive
pid_t childpid;
int size;
childpid = fork();
if(childpid == -1)
error.system("fork error");
if(childpid == 0)
{
// child, will receive data from parent
for(size = 1; size <= size_max; size*=2)
{
for(i = 0; i < NUMBER_REPEAT; i++)
{
if( msgrcv(msgid, buffer, size_max+4, 0, 0) == -1)
error.system("msgrcv error");
}
}
synchronization_signal_parent(getppid());
}
else
{
// parent, will send data to child
measurement mes(argv[0], "write", measure_max);
for(size = 1; size <= size_max; size*=2)
{
// start timer
mes.start(size, NUMBER_REPEAT);
for(i = 0; i < NUMBER_REPEAT; i++)
{
if( msgsnd(msgid, buffer, size, 0) == -1)
error.system("msgsnd error");
}
// end timer
mes.end();
}
// wait till child has read all data
synchronization_wait();
mes.writeout_logfile(true, true, true); // use cout as output file
mes.writeout_plain_logfile(true, false); // and write gnuplot data file
// destroy message queue
if(msgctl(msgid, IPC_RMID, NULL) == -1)
error.system("msgctl error");
}
if(buffer)
free(buffer);
return(EXIT_SUCCESS);
}