私のubuntu 32ビットコンピューターでは、すべてがうまく機能します。しかし、私の友人が以下のコードを試すと、プログラムは中止され、try catch ブロックは失敗します。キャッチオールブロックなので、これは奇妙です。
osm.h:
#ifndef _OSM_H
#define _OSM_H
/* calling a system call that does nothing */
#define OSM_NULLSYSCALL asm volatile( "int $0x80 " : : \
"a" (0xffffffff) /* no such syscall */, "b" (0), "c" (0), "d" (0) /*:\
"eax", "ebx", "ecx", "edx"*/)
/* Time measurement function for an empty function call.
returns time in nano-seconds upon success,
and -1 upon failure.
*/
double osm_function_time(unsigned int osm_iterations);
/* Time measurement function for an empty trap into the operating system.
returns time in nano-seconds upon success,
and -1 upon failure.
*/
double osm_syscall_time(unsigned int osm_iterations);
/* Time measurement function for a simple arithmetic operation.
returns time in nano-seconds upon success,
and -1 upon failure.
*/
double osm_operation_time(unsigned int osm_iterations);
typedef struct {
char* machineName;
int numberOfIterations;
double instructionTimeNanoSecond;
double functionTimeNanoSecond;
double trapTimeNanoSecond;
double functionInstructionRatio;
double trapInstructionRatio;
} timeMeasurmentStructure;
timeMeasurmentStructure measureTimes (unsigned int numOfIterations);
#endif
osm.cpp
#include "osm.h"
#include <cmath>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#define SEC_MICROSEC_RATIO 1000000
#define NANOSEC_MICROSEC_RATIO 1000
#define DEFAULT_NUM_ITERATIONS 50000
#define MAX_MACHINE_NAME 30
#define ERR_CODE -1
void dummy_function()
{
}
double osm_function_time(unsigned int osm_iterations)
{
unsigned int i;
double elapsed = 0;
struct timeval timeFirst, timeSecond;
for (i=0; i<osm_iterations;i++)
{
gettimeofday(&timeFirst, NULL);
dummy_function();
gettimeofday(&timeSecond, NULL);
elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec;
}
return (elapsed / osm_iterations) * NANOSEC_MICROSEC_RATIO;
}
double osm_operation_time(unsigned int osm_iterations)
{
unsigned int i;
int a=1,b=10;
double elapsed = 0;
struct timeval timeFirst, timeSecond;
for (i=0; i<osm_iterations;i++)
{
gettimeofday(&timeFirst, NULL);
a = a + b;
gettimeofday(&timeSecond, NULL);
elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec;
}
return (elapsed / osm_iterations) * NANOSEC_MICROSEC_RATIO;
}
double osm_syscall_time(unsigned int osm_iterations)
{
unsigned int i;
double elapsed = 0;
struct timeval timeFirst, timeSecond;
for (i=0; i<osm_iterations;i++)
{
gettimeofday(&timeFirst, NULL);
OSM_NULLSYSCALL;
gettimeofday(&timeSecond, NULL);
elapsed += (timeSecond.tv_sec-timeFirst.tv_sec)*SEC_MICROSEC_RATIO + timeSecond.tv_usec-timeFirst.tv_usec;
}
return (elapsed / osm_iterations) * NANOSEC_MICROSEC_RATIO;
}
timeMeasurmentStructure measureTimes (unsigned int numOfIterations)
{
if (numOfIterations<=0)
{
numOfIterations = DEFAULT_NUM_ITERATIONS;
}
timeMeasurmentStructure timer;
timer.numberOfIterations = numOfIterations;
// get machine name
timer.machineName = new char[MAX_MACHINE_NAME];
try{
gethostname(timer.machineName,MAX_MACHINE_NAME);
} catch(...){
delete [] timer.machineName;
timer.machineName = NULL;
}
try{
timer.functionTimeNanoSecond = osm_function_time(numOfIterations);
} catch(...){
timer.functionTimeNanoSecond = ERR_CODE;
}
try{
timer.instructionTimeNanoSecond = osm_operation_time(numOfIterations);
} catch(...){
timer.instructionTimeNanoSecond = ERR_CODE;
}
try{
timer.trapTimeNanoSecond = osm_syscall_time(numOfIterations);
} catch(...){
timer.trapTimeNanoSecond = ERR_CODE;
}
// trap/instruction
if((timer.trapInstructionRatio!=ERR_CODE) && (timer.trapTimeNanoSecond!=ERR_CODE))
{
timer.trapInstructionRatio = timer.trapTimeNanoSecond / timer.instructionTimeNanoSecond;
} else
{
timer.trapInstructionRatio = ERR_CODE;
}
// function/instruction
if((timer.functionTimeNanoSecond!=ERR_CODE) && (timer.instructionTimeNanoSecond!=ERR_CODE))
{
timer.functionInstructionRatio = timer.functionTimeNanoSecond / timer.instructionTimeNanoSecond;
} else
{
timer.functionInstructionRatio = ERR_CODE;
}
return timer;
}
main.cpp
#include <iostream>
#include "osm.h"
using namespace std;
int main()
{
timeMeasurmentStructure timeMe = measureTimes(0);
if(timeMe.machineName!=NULL)
{
cout << "machine name: " << timeMe.machineName << endl;
}
cout << "iterations: " << timeMe.numberOfIterations << endl;
cout << "instruction time: " << timeMe.instructionTimeNanoSecond << endl;
cout << "function time: " << timeMe.functionTimeNanoSecond << endl;
cout << "trap time: " << timeMe.trapTimeNanoSecond << endl;
cout << "function/instruction ratio: " << timeMe.functionInstructionRatio << endl;
cout << "trap/instruction ratio: " << timeMe.trapInstructionRatio << endl;
return 0;
}
次の行の場合、彼はスローされます。
OSM_NULLSYSCALL;
と呼ばれます。私はSOがプリントスクリーンを好まないことを知っていますが、OS Xを持っていないので、これがそれを表示する唯一の方法です:
catch ブロックが失敗するのはなぜですか? どうすれば修正できますか?
ノート:
osm.h ファイルをまったく変更できません (演習の一環として)