#include "IOMessage.h"
#include "IOPortTCP.h"
#include "IOPort.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define IDLE (0)
#define WAITCONNECT (1)
#define CONNECTED (2)
class Dynamo
{
#define TESTTING (0x01)
#define UNTEST (0x00)
public:
Dynamo()
{
status = IDLE;
targets = new struct Target_Spec[MAX_TARGETS];
targetsIdArray = new int[MAX_TARGETS];
specs = new Test_Spec[MAX_ACCESS_SPECS];
}
~Dynamo()
{
delete []targets;
delete []targetsIdArray;
delete []specs;
}
bool Login();
bool Exit(int workerid);
char addr[512];
unsigned short portNumber;
int getstatus()
{
return status;
};
void setstatus(int status)
{
this->status = status;
}
void reportTargest();
void setTargets(int workerId);
void addTargetId(int id, int queueDepth, int transPerConn);
void addWorker(int count);
void prepareDisks(int workerId);
void setSpecs(int workerId, struct Test_Spec *spec, int count);
bool startTests(int workerId = ALL_WORKERS);
private:
int status;
PortTCP dynamo;
Message smsg,rmsg;
Data_Message sdatamsg, rdatamsg;
struct Target_Spec *targets;
int targetsCount;
int *targetsIdArray;
int targetIdx;
struct Test_Spec *specs;
};
bool Dynamo::startTests(int workerId)
{
smsg.purpose = START;
smsg.data = workerId;
dynamo.Send((LPVOID)&smsg);
memset(&rmsg, 0, MESSAGE_SIZE);
dynamo.Receive((LPVOID)&rmsg);
if (rmsg.data)
{
printf("start test on workerid (%d) success.\n", workerId);
return true;
}
return false;
}
void Dynamo::prepareDisks(int workerId)
{
smsg.purpose = PREP_DISKS;
smsg.data = workerId;
dynamo.Send((LPVOID)&smsg);
dynamo.Receive((LPVOID)&rmsg, MESSAGE_SIZE);
return;
}
void Dynamo::setSpecs(int workerId, struct Test_Spec *spec, int count)
{
memcpy(specs, spec, count*sizeof(struct Test_Spec));
smsg.purpose = SET_ACCESS;
smsg.data = workerId;
dynamo.Send((LPVOID)&smsg);
sdatamsg.count = count;
memcpy(&sdatamsg.data.spec, spec, count*sizeof(struct Test_Spec));
dynamo.Send((LPVOID)&sdatamsg, DATA_MESSAGE_SIZE);
dynamo.Receive((LPVOID)&rmsg);
}
void Dynamo::addTargetId(int id, int queueDepth, int transPerConn)
{
if (id > MAX_TARGETS)
{
printf("target id out of range(%d),max(%d)\n", id, MAX_TARGETS);
return;
}
targetsIdArray[targetIdx++] = id;
targets[id].queue_depth = queueDepth;
targets[id].test_connection_rate = false;
targets[id].trans_per_conn = transPerConn;
}
void Dynamo::addWorker(int count)
{
smsg.purpose = ADD_WORKERS;
smsg.data = count;
printf("worker count %d\n", count);
if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return;
}
if(dynamo.Receive((LPVOID)&rmsg) != MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return;
}
}
void Dynamo::setTargets(int workerId)
{
int targetToTestCnt = targetIdx;
int i;
smsg.purpose = SET_TARGETS;
smsg.data = workerId;
if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return;
}
sdatamsg.count = targetToTestCnt;
printf("target count = %d\n", targetToTestCnt);
for (int i = 0; i < targetToTestCnt; i++)
{ printf("setting taget %d, name %s\n", targetsIdArray[i], targets[targetsIdArray[i]].name);
memcpy(&sdatamsg.data.targets[i], &targets[targetsIdArray[i]], sizeof(struct Target_Spec));
}
if (dynamo.Send((LPVOID)&sdatamsg, DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return;
}
if (dynamo.Receive((LPVOID)&rdatamsg, DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return;
}
}
void Dynamo::reportTargest()
{
smsg.purpose = REPORT_TARGETS;
if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
{
printf("%d:send message size fail\n", __LINE__);
return ;
}
if (dynamo.Receive((LPVOID)&rdatamsg,DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
{
printf("%d:recv message size fail\n", __LINE__);
return;
}
targetsCount = rdatamsg.count;
memcpy(targets, rdatamsg.data.targets, targetsCount*sizeof(struct Target_Spec));
for (int i = 0; i < targetsCount; i++)
{
printf("ID:[%d],target name(%s), type(%x)\n",
i, rdatamsg.data.targets[i].name, rdatamsg.data.targets[i].type);
}
return;
}
bool Dynamo::Login()
{
if (status != WAITCONNECT)
{
return false;
}
if (dynamo.Connect(addr,portNumber))
{
status= CONNECTED;
return true;
}
return false;
}
bool Dynamo::Exit(int workerid)
{
smsg.purpose= EXIT;
smsg.data = workerid;
if (dynamo.Send((LPVOID)&smsg))
{
status= IDLE;
return true;
}
return false;
}
class DynamoManager
{
#define MAX_DYNAMOS (5)
public:
DynamoManager()
{
listenDyanmo = new PortTCP();
listenDyanmo->Create(NULL, NULL, MESSAGE_PORT_SIZE, WELL_KNOWN_TCP_PORT);
dynamos = new Dynamo[MAX_DYNAMOS];
status = IDLE;
}
void Start()
{
//pthread_create(&newThread, NULL, (void *(*)(void *))AccecptWapper, (void *)this);
//pthread_detach(newThread);
}
int startTestToDynamo(int dynamoId, int workerId = ALL_WORKERS);
pthread_t getThread()
{
return newThread;
}
void setAccessToDynamo(int dynamoId, int workerid, struct Test_Spec * spec,int count);
void setTestTargetToDynamo(int dynamoId,int workerid, int targetId, int queueDepth, int transPerConn);
int LoginAllDynamos()
{
int i;
int connectedNum = 0;
for (i = 0; i < MAX_DYNAMOS; i++)
{
printf("dynamo(%d):status(%d)\n", i, dynamos[i].getstatus());
if (dynamos[i].Login())
connectedNum++;
}
return connectedNum;
}
void ExitDynamobyId(int id, int workerCount)
{
dynamos[id].Exit(workerCount);
}
void reportTargetbyId(int id)
{
printf("=====================\n");
dynamos[id].reportTargest();
printf("=====================\n");
}
void prepDiskToDynamo(int dynamoId, int workerId);
~DynamoManager()
{
delete listenDyanmo;
delete []dynamos;
}
Dynamo* GetOneDynamo(int id)
{
return &dynamos[id];
}
int getStaus()
{
return status;
}
void addWorkerToDynamo(int dynamoId, int count);
bool Accept()
{
if (!listenDyanmo->Accept())
{
}
listenDyanmo->Receive((LPVOID)&msg);
if (msg.purpose != LOGIN)
{
printf("bad message\n");
return false;
}
listenDyanmo->Receive((LPVOID)&data_msg, DATA_MESSAGE_SIZE);
msg.data = LOGIN_OK;
listenDyanmo->Send((LPVOID)&msg);
int i;
for (i = 0; i < MAX_DYNAMOS; i++)
{
if (dynamos[i].getstatus() == IDLE)
{
strncpy((char *)&dynamos[i].addr, "127.0.0.1", 512);
dynamos[i].portNumber = data_msg.data.manager_info.port_number;
dynamos[i].setstatus(WAITCONNECT);
printf("dynamoid(%d), name(%s), port_number(%u), processors(%d), speed(%f), version(%s)\n",
i,data_msg.data.manager_info.names[0], data_msg.data.manager_info.port_number,
data_msg.data.manager_info.processors,data_msg.data.manager_info.processor_speed,
data_msg.data.manager_info.version);
break;
}
}
if (MAX_DYNAMOS == i)
{
//send max login message
}
return true;
}
protected:
PortTCP *listenDyanmo;
Dynamo *dynamos;
int status;
Message msg;
Data_Message data_msg;
pthread_t newThread;
};
void DynamoManager::setTestTargetToDynamo(int dynamoId,int workerid, int targetId, int queueDepth, int transPerConn)
{
dynamos[dynamoId].addTargetId(targetId, queueDepth, transPerConn);
dynamos[dynamoId].setTargets(workerid);
}
int DynamoManager::startTestToDynamo(int dynamoId,int workerId)
{
dynamos[dynamoId].startTests(workerId);
}
void DynamoManager::setAccessToDynamo(int dynamoId, int workerid, struct Test_Spec * spec,int count)
{
dynamos[dynamoId].setSpecs(workerid,spec,count);
}
void DynamoManager::addWorkerToDynamo(int dynamoId, int count)
{
if (dynamoId > MAX_DYNAMOS)
{
printf("out max dynamos\n");
}
dynamos[dynamoId].addWorker(count);
}
void DynamoManager::prepDiskToDynamo(int dynamoId, int workerId)
{
dynamos[dynamoId].prepareDisks(workerId);
}
void AccecptWapper(void *dynamoManager)
{
DynamoManager *dm = (DynamoManager *)dynamoManager;
while(dm->getStaus() != IDLE)
{
if (dm->Accept())
{
return;
}
}
}
int main(int argc, char *argv)
{
DynamoManager dm;
int i = 0;
struct Test_Spec spec;
Access_Spec *tmpAcc = spec.access;
strncpy((char *)spec.name, "tata", MAX_WORKER_NAME);
spec.default_assignment = 0;
tmpAcc[0].align = 0;
tmpAcc[0].burst = 0;
tmpAcc[0].delay = 0;
tmpAcc[0].of_size = 100;
tmpAcc[0].random = 0;
tmpAcc[0].reads = 100;
tmpAcc[0].reply = 0;
tmpAcc[0].size = 512;
//for (; i < 2; i++)
//{
dm.Accept();
//}
printf("conneced %d dynamoes\n",dm.LoginAllDynamos());
dm.reportTargetbyId(0);
dm.addWorkerToDynamo(0, 1);
//dm.addWorkerToDynamo(0, 2);
dm.setTestTargetToDynamo(0, 0, 4,1,1);
//dm.prepDiskToDynamo(0, 0);
dm.setAccessToDynamo(0,0,&spec,1);
dm.startTestToDynamo(0,0);
while(1)
{
sleep(1);
printf("idle...\n");
}
dm.ExitDynamobyId(0, 1);
return 0;
}
=====================================================================
makefile
###############################################################################
## ##
## Dynamo / Makefile-Linux.i386 ##
## ##
## ------------------------------------------------------------------------- ##
## ##
## Job .......: The Makefile for the GNU/Linux on i386 variant. ##
## ##
## ------------------------------------------------------------------------- ##
## ##
## Intel Open Source License ##
## ##
## Copyright (c) 2001 Intel Corporation ##
## All rights reserved. ##
## Redistribution and use in source and binary forms, with or without ##
## modification, are permitted provided that the following conditions ##
## are met: ##
## ##
## Redistributions of source code must retain the above copyright notice, ##
## this list of conditions and the following disclaimer. ##
## ##
## Redistributions in binary form must reproduce the above copyright ##
## notice, this list of conditions and the following disclaimer in the ##
## documentation and/or other materials provided with the distribution. ##
## ##
## Neither the name of the Intel Corporation nor the names of its ##
## contributors may be used to endorse or promote products derived from ##
## this software without specific prior written permission. ##
## ##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ##
## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ##
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ##
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ##
## ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ##
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ##
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ##
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ##
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ##
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ##
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##
## ##
## ------------------------------------------------------------------------- ##
## ##
## Remarks ...: <none> ##
## ##
## ------------------------------------------------------------------------- ##
## ##
## Changes ...: 2005-02-26 (mingz@ele.uri.edu) ##
## - Added NOMINMAX definition. ##
## 2004-08-21 (daniel.scheibli@edelbyte.org) ##
## - Removed old global defines that are no longer used / ##
## named different, like IOMTR_SETTING_OVERRIDE_FS ##
## - Removed IOPerformance.o from the list of objects to ##
## be linked, as for Linux only IOPerformanceLinux.o is ##
## relevant. ##
## 2004-08-07 (daniel.scheibli@edelbyte.org) ##
## - Added iometer target and explained that there is no ##
## Iometer GUI for non MS Windows platforms so far. ##
## 2004-03-28 (daniel.scheibli@edelbyte.org) ##
## - Removed the IOManagerSolaris.o module from the list of ##
## Objects (OBJECTS) - as suggested by Ming Zhang. ##
## 2003-12-21 (daniel.scheibli@edelbyte.org) ##
## - Changed DYNAMO_DESTRUCTIVE to IOMTR_SETTING_OVERRIDE_FS ##
## - Changed NO_DYNAMO_VI to IOMTR_SETTING_VI_SUPPORT ##
## 2003-07-27 (daniel.scheibli@edelbyte.org) ##
## - Removed the [BIG|LITTLE]_ENDIAN_ARCH defines, because ##
## they have been replaced by IsBigEndian() function calls. ##
## 2003-07-13 (daniel.scheibli@edelbyte.org) ##
## - Minor cleanup of this file. ##
## - Implemented the IOMTR_[OSFAMILY|OS|CPU]_* global define ##
## as well as their integrity checks. ##
## - Integrated the License Statement into this header. ##
## 2003-03-05 (daniel.scheibli@edelbyte.org) ##
## - Removed LINUX_DEBUG, because it is redundant. ##
## We can use the generic _DEBUG therefor. ##
## 2003-03-04 (joe@eiler.net) ##
## - Changed NO_LINUX_VI to be NO_DYNAMO_VI ##
## - Merged rdtsc.c into IOTime.cpp ##
## - Some minor cleanup ##
## 2003-02-09 (daniel.scheibli@edelbyte.org) ##
## - Added the default variable CXX again. ##
## 2003-02-02 (daniel.scheibli@edelbyte.org) ##
## - Added new header holding the changelog. ##
## - Applied the iometer-initial-largefile.patch file ##
## (brings some global defines). ##
## - Removed the "depend" target related stuff. ##
## - Added the typical "all" target. ##
## - Removed AS, CC and changed STRIP variable. ##
## - Swapped the librt.a patch stuff, because it is more ##
## common, that someone runs a glibc version 2.2 or later ##
## then running an old one. ##
## - Sort of the object file list (OBJECTS variable). ##
## ##
###############################################################################
.MAKE_VERSION: VERSION-1.0
# un-comment out .IGNORE to suppress error messages and not stop make on errors.
#.IGNORE:
.SUFFIXES: .cpp .c .o
RM=/bin/rm -f
MV=/bin/mv
TOUCH=/usr/bin/touch
STRIP=/usr/bin/strip
# Some common definitions used.
# Note 1) -DWORKAROUND_MOD_BUG can be dropped if -O is used in place of -g in CFLAGS
# Note 2) -D_DETAILS=1 -D_DEBUG enables maximum debug information
#CFLAGS= -O3
#CFLAGS=-Wall
CFLAGS= -Wall \
-D_GNU_SOURCE \
-DIOMTR_OSFAMILY_UNIX -DIOMTR_OS_LINUX \
-DIOMTR_CPU_I386 \
-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \
-D_REENTRANT -DNOMINMAX \
-ggdb
# For older versions of the librt.a it is needed to apply a patch (see the
# file "Documentation/LinuxReadme.txt" for an explanation of the patch,
# and "Documentation/linux-rt-2.1.2.patch" for the patch itself).
# If you have glibc version less then 2.2, the patch is needed; in this
# case, change this line as follows:
#
# LDFLAGS= ../glibc-2.1/rt/librt.a -lpthread
LDFLAGS= -lrt -lpthread
OBJECTS= IOGlobals.o \
Pulsar.o \
IOManager.o IOManagerLinux.o \
IOGrunt.o \
IOTarget.o IOTargetDisk.o IOTargetTCP.o \
IOPort.o IOPortTCP.o \
Network.o NetTCP.o \
ByteOrder.o \
IOPerformanceLinux.o \
IOTime.o \
IOCQAIO.o IOCompletionQ.o \
IOAccess.o
IOMANAGEROBJS=IOPort.o \
IOPortTCP.o \
IOCommand.o \
IOCompletionQ.o
# Make Rules
help:
@echo
@echo "Please pick one of the listed targets:"
@echo
@echo " all Build the binaries"
@echo " dynamo Build the dynamo binary"
@echo " iometer Build the iometer binary (not supported) *"
@echo " clean Remove old binaries and object files"
@echo
@echo " * = The Iometer GUI is so far only available for MS Windows,"
@echo " but you can use it to control dynamo's running on Linux."
@echo
all: dynamo, iocommand
dynamo: $(OBJECTS)
$(CXX) $(CFLAGS) -o dynamo $(OBJECTS) $(LIBS) $(LDFLAGS)
iocommand: $(IOMANAGEROBJS)
$(CXX) $(CFLAGS) -o iocommand $(IOMANAGEROBJS) $(LIBS) $(LDFLAGS)
clean:
$(RM) $(OBJECTS) dynamo
install:
echo "Not Supported."
iometer:
echo "Not Supported."
.cpp.o:
$(CXX) $(CFLAGS) -c $<
.c.o:
$(CXX) $(CFLAGS) -c $<