//------------------------------------------------------------------------------ //! @file XrdStress.cc //! @author Elvin-Alin Sindrilaru - CERN //! @brief Class capable of doing a stress test ( read/write operations) on the //! files of a directory using either threads or processes. //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2011 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ /*-----------------------------------------------------------------------------*/ #include /*-----------------------------------------------------------------------------*/ #define DELTATIME 10 ///< print statistics every 10 seconds typedef void* ( *TypeFunc )( void* ); class XrdStress; //------------------------------------------------------------------------------ //! Struct ChildInfo //------------------------------------------------------------------------------ struct ChildInfo { int idChild; ///< child id XrdStress* pXrdStress; ///< pointer to the test class double avgRdVal; ///< avg read value for current thread double avgWrVal; ///< avg write value for current thread double avgOpenVal; ///< avg open value for current thread }; //------------------------------------------------------------------------------ //! Class XrdStress //------------------------------------------------------------------------------ class XrdStress { public: //-------------------------------------------------------------------------- //! Constructor //-------------------------------------------------------------------------- XrdStress( unsigned int nChilds, unsigned int nFiles, size_t sBlock, off_t sFile, std::string pTest, std::string op, bool verb, bool processmode, bool concurrent ); //-------------------------------------------------------------------------- //! Destructor //-------------------------------------------------------------------------- ~XrdStress(); //-------------------------------------------------------------------------- //! Entry function to start running tests //-------------------------------------------------------------------------- void RunTest(); private: bool verbose; ///< verbose mode on bool processMode; ///< run test using processes, else threads bool concurrentMode; ///< all jobs process the same files off_t sizeFile; ///< size of file used for testing size_t sizeBlock; ///< block size for operations (rd/wr) TypeFunc callback; ///< type of operation executed unsigned int numChilds; ///< number of children used ( threads/processes ) unsigned int numFiles; ///< number of files used for the test per child std::string pathTest; ///< directory where the testing takes place std::string opType; ///< type of operation ( rd/wr/rdwr ) std::string childType; ///< type or children ( threads/processes ) std::vector avgRdRate; ///< avg read rate per child std::vector avgWrRate; ///< avg write rate per child std::vector avgOpen; ///< avg open operations per child std::vector vectChilds; ///< vector of children std::vector vectFilename; ///< vector of all files used //-------------------------------------------------------------------------- //! Run test using threads //-------------------------------------------------------------------------- void RunTestThreads(); //-------------------------------------------------------------------------- //! Run test using processes //-------------------------------------------------------------------------- void RunTestProcesses(); //-------------------------------------------------------------------------- //! Wait for a process to finish and evaluate the return code //! //! @param pid process id //! //! @return rc return code of process //-------------------------------------------------------------------------- int WaitProcess(pid_t pid); //-------------------------------------------------------------------------- //! Wait for all threads to finish //-------------------------------------------------------------------------- void WaitThreads(); //-------------------------------------------------------------------------- //! Start thread executing a particular function //! //! @param thread thread to be started //! @param func function to be executed by the thread //! @param arg arguments to the function //! //! @return 0 if successful, errno otherwise //! //-------------------------------------------------------------------------- int ThreadStart( pthread_t& thread, TypeFunc func, void* arg ); //-------------------------------------------------------------------------- //! Compute statistics for all jobs //-------------------------------------------------------------------------- void ComputeStatistics(); //-------------------------------------------------------------------------- //! Compute standard deviation and mean for current input //! //! @param avg average value (rd/wr) per child //! @param mean the mean value of all jobs //! //! @return std. dev of all jobs //! //-------------------------------------------------------------------------- double GetStdDev( std::vector& avg, double& mean ); //-------------------------------------------------------------------------- //! Read the name of the files from the directory //! //! @return the number of files in the directory //! //-------------------------------------------------------------------------- int GetListFilenames(); //-------------------------------------------------------------------------- //! Read procedure //! //! @param arg pointer to child info structure passed around //! //! @return pointer to updated child info structure //! //-------------------------------------------------------------------------- static void* RdProc( void* arg ); //-------------------------------------------------------------------------- //! Write procedure //! //! @param arg pointer to child info structure passed around //! //! @return pointer to updated child info structure //! //-------------------------------------------------------------------------- static void* WrProc( void* arg ); //-------------------------------------------------------------------------- //! Read-write procedure //! //! @param arg pointer to child info structure passed around //! //! @return pointer to updated child info structure //! //-------------------------------------------------------------------------- static void* RdWrProc( void* arg ); };