diff options
author | Aleksandar Donchev <Aleksander.Donchev@partner.bmw.de> | 2017-11-27 15:39:53 +0100 |
---|---|---|
committer | Jacqueline Molz <Jacqueline.Molz@bmw.de> | 2017-12-04 08:20:14 +0100 |
commit | 849e645ac9a88c7c49c8b876276c57e064442dd0 (patch) | |
tree | 7f92c2313db1a94227d5456829ed2e55ae039fd3 /AudioManagerUtilities | |
parent | b8f091112d49c6e2e4695a4e813e2f8a0ce20f6e (diff) | |
download | audiomanager-849e645ac9a88c7c49c8b876276c57e064442dd0.tar.gz |
Cmake parameters for real-time scheduler's priority and policy and throw runtime error if read fails.
Signed-off-by: Christian Linke <christian.linke@bmw.de>
Change-Id: I6a7a2c424bc8fac62c76a66545a231c518edb2e1
Diffstat (limited to 'AudioManagerUtilities')
4 files changed, 97 insertions, 55 deletions
diff --git a/AudioManagerUtilities/include/CAmSocketHandler.h b/AudioManagerUtilities/include/CAmSocketHandler.h index 53010ba..2fd5c42 100644 --- a/AudioManagerUtilities/include/CAmSocketHandler.h +++ b/AudioManagerUtilities/include/CAmSocketHandler.h @@ -492,7 +492,29 @@ public: void exit_mainloop(); bool fatalErrorOccurred(); +#ifdef WITH_REALTIME_SCHEDULER + /** + * Set scheduling algorithm and/or parameters for a thread whose ID is specified in pid. + * If pid equals zero, the scheduling policy and parameters of the calling thread will be set. + * @param pid_t pid thread id + * @param int policy equals specified policies in sched_setscheduler documentation + * @param int priority between 1 and 99 + * @return on success 0 and on error -1 + */ + static int setRuntimeScheduler(const pid_t pid, const int policy, const int priority); +#endif }; +#ifdef WITH_REALTIME_SCHEDULER +#define SET_REALTIME_SCHEDULER()\ + if ( CAmSocketHandler::setRuntimeScheduler(0, AM_REALTIME_POLICY, AM_PROCESS_PRIORITY) != 0 )\ + {\ + std::cerr <<"sched_setscheduler:"<<strerror(errno)<<std::endl;\ + std::cerr << "Try running as root"<<std::endl;\ + } +#else +#define SET_REALTIME_SCHEDULER() +#endif + } /* namespace am */ #endif /* SOCKETHANDLER_H_ */ diff --git a/AudioManagerUtilities/src/CAmSocketHandler.cpp b/AudioManagerUtilities/src/CAmSocketHandler.cpp index 250d731..ef5d09a 100644 --- a/AudioManagerUtilities/src/CAmSocketHandler.cpp +++ b/AudioManagerUtilities/src/CAmSocketHandler.cpp @@ -246,9 +246,22 @@ void CAmSocketHandler::exit_mainloop() bool CAmSocketHandler::fatalErrorOccurred() { - return ((mInternalCodes&internal_codes_e::PIPE_ERROR)>0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); + return ((mInternalCodes&internal_codes_e::PIPE_ERROR)>0)||((mInternalCodes&internal_codes_e::FD_ERROR)>0); } +#ifdef WITH_REALTIME_SCHEDULER +int CAmSocketHandler::setRuntimeScheduler(const pid_t pid, const int policy, const int priority) +{ + //The following structure is used to set a processes priority + struct sched_param param; + //Set the priority of the process + param.sched_priority = priority; + + int ret = sched_setscheduler(pid, policy, & param); + return ret; +} +#endif + am_Error_e CAmSocketHandler::getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData) { VectorListPoll_t::iterator iterator = mListPoll.begin(); @@ -324,7 +337,7 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector<uint8_t> & listSi if(0==mSignalFdHandle) { /* Create the signalfd */ - int signalHandlerFd = signalfd(-1, &sigset, 0); + int signalHandlerFd = signalfd(-1, &sigset, SFD_NONBLOCK); if (signalHandlerFd == -1) { logError("Could not open signal fd!"); @@ -337,8 +350,13 @@ am_Error_e CAmSocketHandler::listenToSignals(const std::vector<uint8_t> & listSi /* We have a valid signal, read the info from the fd */ struct signalfd_siginfo info; ssize_t bytes = read(pollfd.fd, &info, sizeof(info)); - assert(bytes == sizeof(info)); - + if(bytes != sizeof(info)) + { + //error received... + logError("Failed to read from signal fd"); + throw std::runtime_error(std::string("Failed to read from signal fd.")); + } + /* Notify all listeners */ for(auto it: signalHandlers) it.callback(it.handle, info, it.userData); @@ -608,13 +626,14 @@ am_Error_e CAmSocketHandler::addTimer(const timespec & timeouts, std::function<v return err; } - auto actionPoll = [](const pollfd pollfd, const sh_pollHandle_t handle, void* userData) + auto actionPoll = [this](const pollfd pollfd, const sh_pollHandle_t handle, void* userData) { uint64_t mExpirations; - if (read(pollfd.fd, &mExpirations, sizeof(uint64_t)) == -1) + if(read(pollfd.fd, &mExpirations, sizeof(uint64_t))!=sizeof(uint64_t)) { - //error received...try again - read(pollfd.fd, &mExpirations, sizeof(uint64_t)); + //error received... + logError("Failed to read from timer fd"); + throw std::runtime_error(std::string("Failed to read from timer fd.")); } }; diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index b0c00d4..c4af4c1 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -30,11 +30,9 @@ #include <fcntl.h> #include <sys/un.h> #include <sys/poll.h> - +#include "CAmDltWrapper.h" #include "CAmSocketHandler.h" -//todo: expand test, implement more usecases -//todo: test removeFD #undef ENABLED_SOCKETHANDLER_TEST_OUTPUT #undef ENABLED_TIMERS_TEST_OUTPUT @@ -274,10 +272,11 @@ void* playWithSocketServer(void* data) servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*) (host->h_addr_list[0]))); servAddr.sin_port = htons(servPort); sleep(1); - - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if (ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -299,10 +298,11 @@ void* playWithUnixSocketServer(void* data) strcpy(servAddr.sun_path, SOCK_PATH); servAddr.sun_family = AF_UNIX; sleep(1); - - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if ( ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -314,8 +314,6 @@ void* playWithUnixSocketServer(void* data) send(socket_, stringToSend.c_str(), stringToSend.size(), 0); return (NULL); - - } void* threadCallbackUnixSocketAndTimers(void* data) @@ -326,9 +324,11 @@ void* threadCallbackUnixSocketAndTimers(void* data) strcpy(servAddr.sun_path, SOCK_PATH); servAddr.sun_family = AF_UNIX; sleep(1); - if (connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + int ret = connect(socket_, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if ( ret < 0) { - std::cout << "ERROR: connect() failed\n" << std::endl; + std::cerr << "ERROR: connect() failed\n" << std::endl; + return (NULL); } for (int i = 1; i <= SOCKET_TEST_LOOPS_COUNT; i++) @@ -369,6 +369,7 @@ TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) { std::cout << "socket problem" << std::endl; } + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, threadCallbackUnixSocketAndTimers, &socket_); @@ -376,6 +377,7 @@ TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) myHandler.start_listenting(); pthread_join(serverThread, NULL); + shutdown(socket_, SHUT_RDWR); } TEST(CAmSocketHandlerTest, timersOneshot) @@ -709,6 +711,7 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) ASSERT_FALSE(myHandler.fatalErrorOccurred()); CAmSamplePlugin::sockType_e type = CAmSamplePlugin::UNIX; CAmSamplePlugin myplugin(&myHandler, type); + ASSERT_TRUE(myplugin.isSocketOpened()); EXPECT_CALL(myplugin,receiveData(_,_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); @@ -718,14 +721,14 @@ TEST(CAmSocketHandlerTest,playWithUNIXSockets) { std::cout << "socket problem" << std::endl; } - + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, playWithUnixSocketServer, &socket_); myHandler.start_listenting(); pthread_join(serverThread, NULL); - + shutdown(socket_, SHUT_RDWR); } TEST(CAmSocketHandlerTest,playWithSockets) @@ -737,7 +740,7 @@ TEST(CAmSocketHandlerTest,playWithSockets) ASSERT_FALSE(myHandler.fatalErrorOccurred()); CAmSamplePlugin::sockType_e type = CAmSamplePlugin::INET; CAmSamplePlugin myplugin(&myHandler, type); - + ASSERT_TRUE(myplugin.isSocketOpened()); EXPECT_CALL(myplugin,receiveData(_,_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,dispatchData(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); EXPECT_CALL(myplugin,check(_,_)).Times(SOCKET_TEST_LOOPS_COUNT + 1); @@ -745,28 +748,24 @@ TEST(CAmSocketHandlerTest,playWithSockets) if ((socket_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { std::cout << "socket problem" << std::endl; - } - + ASSERT_GT(socket_, -1); //creates a thread that handles the serverpart pthread_create(&serverThread, NULL, playWithSocketServer, &socket_); myHandler.start_listenting(); pthread_join(serverThread, NULL); - + shutdown(socket_, SHUT_RDWR); } int main(int argc, char **argv) { - struct sched_param param; - param.sched_priority = 50;//mid rt proprity - if (sched_setscheduler(0, SCHED_FIFO, & param) != 0) - { - std::cerr <<"sched_setscheduler:"<<strerror(errno)<<std::endl; - std::cerr << "Try running as root"<<std::endl; - } - + //Set runtime-scheduler with priority and policy for all threads. You can define the priority and policy via cmake. + //If the cmake option WITH_REALTIME_SCHEDULER is OFF the following macro is empty. + //If a thread needs other settings you can use CAmSocketHandler::setRuntimeScheduler(...) + SET_REALTIME_SCHEDULER() + ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } @@ -779,11 +778,11 @@ am::CAmSamplePlugin::CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType mSocketHandler(mySocketHandler), // mConnecthandle(), // mReceiveHandle(), // - msgList() + msgList(), + mSocket(-1) { int yes = 1; - int socketHandle; struct sockaddr_in servAddr; struct sockaddr_un unixAddr; unsigned int servPort = 6060; @@ -791,26 +790,30 @@ am::CAmSamplePlugin::CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType switch (socketType) { case UNIX: - socketHandle = socket(AF_UNIX, SOCK_STREAM, 0); + mSocket = socket(AF_UNIX, SOCK_STREAM, 0); + if(mSocket==-1) + return; unixAddr.sun_family = AF_UNIX; strcpy(unixAddr.sun_path, SOCK_PATH); unlink(unixAddr.sun_path); - bind(socketHandle, (struct sockaddr *) &unixAddr, strlen(unixAddr.sun_path) + sizeof(unixAddr.sun_family)); + bind(mSocket, (struct sockaddr *) &unixAddr, strlen(unixAddr.sun_path) + sizeof(unixAddr.sun_family)); break; case INET: - socketHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - setsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + mSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if(mSocket==-1) + return; + setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = INADDR_ANY; servAddr.sin_port = htons(servPort); - bind(socketHandle, (struct sockaddr *) &servAddr, sizeof(servAddr)); + bind(mSocket, (struct sockaddr *) &servAddr, sizeof(servAddr)); break; default: break; } - if (listen(socketHandle, 3) < 0) + if (listen(mSocket, 3) < 0) { #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT std::cout << "listen ok" << std::endl; @@ -818,12 +821,12 @@ am::CAmSamplePlugin::CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType } /* if */ int a = 1; - ioctl(socketHandle, FIONBIO, (char *) &a); - setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof(a)); + ioctl(mSocket, FIONBIO, (char *) &a); + setsockopt(mSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &a, sizeof(a)); short events = 0; events |= POLLIN; - mySocketHandler->addFDPoll(socketHandle, events, NULL, &connectFiredCB, NULL, NULL, NULL, mConnecthandle); + mySocketHandler->addFDPoll(mSocket, events, NULL, &connectFiredCB, NULL, NULL, NULL, mConnecthandle); #ifdef ENABLED_SOCKETHANDLER_TEST_OUTPUT std::cout << "setup server - listening" << std::endl; #endif diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h index 269e5da..6cda2b3 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.h @@ -101,10 +101,7 @@ namespace am UNIX, INET }; CAmSamplePlugin(CAmSocketHandler *mySocketHandler, sockType_e socketType); - virtual ~CAmSamplePlugin() - { - } - ; + virtual ~CAmSamplePlugin(){ shutdown(mSocket, SHUT_RDWR); } void connectSocket(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); @@ -113,11 +110,12 @@ namespace am TAmShPollFired<CAmSamplePlugin> receiveFiredCB; TAmShPollDispatch<CAmSamplePlugin> sampleDispatchCB; TAmShPollCheck<CAmSamplePlugin> sampleCheckCB; - + bool isSocketOpened() { return mSocket>-1; } protected: CAmSocketHandler *mSocketHandler; sh_pollHandle_t mConnecthandle, mReceiveHandle; std::queue<std::string> msgList; + int mSocket; }; class CAmTimerSockethandlerController: public MockIAmTimerCb @@ -242,11 +240,11 @@ namespace am std::vector<CAmTimerStressTest2*> mTimers; public: CAmSamplePluginStressTest(CAmSocketHandler *mySocketHandler, sockType_e socketType); - ~CAmSamplePluginStressTest(); + virtual ~CAmSamplePluginStressTest(); - virtual void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData); - virtual bool dispatchData(const sh_pollHandle_t handle, void* userData); - virtual bool check(const sh_pollHandle_t handle, void* userData); + void receiveData(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) final; + bool dispatchData(const sh_pollHandle_t handle, void* userData) final; + bool check(const sh_pollHandle_t handle, void* userData) final; std::vector<CAmTimerStressTest2*> & getTimers() { return mTimers; } }; |