|
From: | Arda TEKIN |
Subject: | [osip-dev] osip/eXosip performance for a basic redirect server application |
Date: | Tue, 29 Jan 2013 11:31:46 +0200 |
Hi Aymeric, I would like to implement high performance redirect server with osip/eXosip. This server will receive and INVITE message, then send 302 respose and finally receive ACK. As a signalling point of it, that's it. My expecation is that this server application should be able to accept 4000-6000 CPS on time and give the appropriate response in a high performance server hardware. I have written a test program using eXosip, osip thread functions and stl collections to be able to understand the basic results. INVITE requests sent from sipp. Server application consumed more then %100cpu around 200CPS on 8 core >3Ghz rack server and couldn't accept further requests. Sipp retransmissions started and stability lost right away. I have also profiled this application with Valgrind and verified that all functions worked as expected with what their original cpu consumption values are. Below, you can find my test application. Could you advise if I am doing something wrong. Should we apply some basic optimizations on stacks/application to improve the overall performance. Kind Regards, Arda ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <syslog.h> #ifndef OSIP_MONOTHREAD #include <pthread.h> #endif #include <osip2/osip_mt.h> #include <eXosip2/eXosip.h> #include <deque> using namespace std; eXosip_t *ctx; int port=5060; #define MAX_THREADS 50 typedef deque<eXosip_event_t *> EventQueue; class CThread { public: CThread() {}; ~CThread() {}; public: void Start(); static void *ThreadFunc(void *pArg); virtual int WorkerFunc() = 0; }; void *CThread::ThreadFunc(void *pArg) { CThread *pThread = (CThread *) pArg; pThread->WorkerFunc(); return NULL; } void CThread::Start() { osip_thread *pThread = NULL; pThread = osip_thread_create(20000, ThreadFunc, this); } class CHandler : public CThread { public: CHandler(int nID) { m_nID = nID; m_pMutexEvent = osip_mutex_init(); m_pSemaphore = osip_sem_init(1); }; ~CHandler() { osip_mutex_destroy(m_pMutexEvent); osip_sem_destroy(m_pSemaphore); }; public: int m_nID; osip_mutex *m_pMutexEvent; osip_sem *m_pSemaphore; EventQueue m_EventQueue; public: void AddEvent(eXosip_event_t *pEvent) { osip_mutex_lock(m_pMutexEvent); m_EventQueue.push_back(pEvent); osip_mutex_unlock(m_pMutexEvent); osip_sem_post(m_pSemaphore); } eXosip_event_t *GetEvent() { eXosip_event_t *pEvent = NULL; osip_mutex_lock(m_pMutexEvent); if (m_EventQueue.size() > 0) { pEvent = m_EventQueue.front(); if (pEvent) m_EventQueue.pop_front(); } osip_mutex_unlock(m_pMutexEvent); return pEvent; } virtual int WorkerFunc() { while (true) { osip_sem_wait(m_pSemaphore); eXosip_event_t *pEvent = GetEvent(); while (pEvent) { eXosip_lock(ctx); eXosip_call_send_answer(ctx, pEvent->tid, 302, NULL); eXosip_unlock(ctx); //printf("%d. thread handled the packet\n", m_nID); eXosip_event_free(pEvent); pEvent = GetEvent(); } } return 0; } }; CHandler *pHandler[MAX_THREADS]; void CreateThreadPool() { for (int i = 0; i < MAX_THREADS; ++i) { pHandler[i] = new CHandler(i); pHandler[i]->Start(); } } int main(int argc, char *argv[]) { TRACE_INITIALIZE(6, NULL); int i; int nIndex = 0; CreateThreadPool(); ctx = eXosip_malloc(); if (ctx == NULL) return -1; i = eXosip_init(ctx); if (i != 0) return -1; i = eXosip_listen_addr(ctx, IPPROTO_UDP, NULL, port, AF_INET, 0); if (i != 0) { eXosip_quit(ctx); fprintf(stderr, "could not initialize transport layer\n"); return -1; } eXosip_event_t *evt; for (;;) { evt = eXosip_event_wait(ctx, 0, 1); eXosip_lock(ctx); eXosip_automatic_action(ctx); eXosip_unlock(ctx); if (evt == NULL) continue; if (evt->type == EXOSIP_CALL_INVITE) { pHandler[nIndex]->AddEvent(evt); nIndex++; nIndex = nIndex % MAX_THREADS; } else if (evt->type == EXOSIP_CALL_ACK) { } else if (evt->type == EXOSIP_CALL_ANSWERED) { } else { eXosip_event_free(evt); } } return 0; } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// |
[Prev in Thread] | Current Thread | [Next in Thread] |