osip-dev
[Top][All Lists]
Advanced

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

Re: [osip-dev] osip/eXosip performance for a basic redirect server appli


From: Aymeric Moizard
Subject: Re: [osip-dev] osip/eXosip performance for a basic redirect server application
Date: Wed, 30 Jan 2013 11:14:42 +0100

Hi Arda,

I guess "logs" can be a reason for lower performance: you can even try to compile
without log support, ie without -DENABLE_TRACE

osip & eXosip2 targets to be used in end-point and as such don't focus on performance.

The first verification you can make is about DNS: your app shouldn't need to make an DNS
request (which would slow the performance).

The issue with your implementation is that there is only on big lock: eXosip_lock/eXosip_unlock
and only one eXosip_t context: so one long list of "osip_transaction_t" where the app is going
through.

You need to split eXosip_t context in several ones. (so they need to run on different network
port: 5060, 5062, 5064; 5066, etc...) May be you can find some easy way to dispatch the
traffic with NAT rules or any other means? That would help.

Using several eXosip_t would allow eXosip_lock to not lock "everything": that's a start.

Of course, if you use one eXosip_t per thread, you can also move to the non-threaded
version of osip and eXosip. You'll certainly get a little more fine grain tuning capability
and eXosip_lock/eXosip_unlock API will be removed.

I'm sure that
N eXosip with each one running X call
will behave better than
1 eXosip running N*X call

Keep me informed!

Regards,
Aymeric

2013/1/29 Arda TEKIN <address@hidden>

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;

}

 

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

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

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


_______________________________________________
osip-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/osip-dev




--
Antisip - http://www.antisip.com

reply via email to

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