osip-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[osip-dev] osip/eXosip performance for a basic redirect server applicati


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;

}

 

//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////


reply via email to

[Prev in Thread] Current Thread [Next in Thread]