Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: TnKernel и очереди
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
megajohn
на данный момент одна задача шлет в другую следующие структуры
Код
typedef struct{
    u8 id;
    void* buff;
    u16 buff_len;
    u16 arg;
}Smsg;


Но так как очереди в tnKernel это void* то приходится

Код
send:
Smsg* item = MALLOC( sizeof(Smsg) );
item->id=...
item->buff=...
....
tn_queue_send(...);


для увеличения скорости видится такая реализация

Код
#define QUE_ITEMS 10
Smsg que[QUE_ITEMS];

tn_queue2_create( ..., (void*)que, sizeof( Smsg ), QUE_ITEMS )

Smsg item;
item.id=...
item.buff=...
tn_queue_send( &item );


то есть избавляемся от кучи

Собсвенно вопрос: кто-нибудь такое реализовывал и может поделится ?
А то задача тривиальная и обыденная, а лисапед не хочется писать =)
demiurg_spb
Цитата(megajohn @ Mar 27 2013, 13:33) *
Но так как очереди в tnKernel это void* то приходится
Код
Smsg* item = MALLOC( sizeof(Smsg) );
ИМХО неоднозначное умозаключение.
megajohn
вообщем, нужно что-то вроде mailbox (с изменяемым размером). Ща подосвобожусь и сделаю
Axel
А чем не угодил "TNkernel-овский" MemPool?
dac
не совсем понял задачу, точнее все мои варианты сводятся к MemPool или пересылке указателя и копирования структуры в месте преима. оба варината расписаны в доке к тнкернелу
megajohn
Цитата(dac)
не совсем понял задачу, точнее все мои варианты сводятся к MemPool или пересылке указателя и копирования структуры в месте преима. оба варината расписаны в доке к тнкернелу


Цитата(Axel)
А чем не угодил "TNkernel-овский" MemPool?


Не угодил лишними операциями.

то есть отправка структуры из задачи A в задачу B в рамках TN-Kernel выглядит так
tn_fmem_get_polling
tn_queue_send
tn_queue_receive
tn_fmem_release


я сделал mailbox и получилось так
tn_mbox_send
tn_mbox_receive


В итоге, код стал не таким загроможденным
и получил хоть малый (13% на моих тестах)но выигрыш в производительности

В аттаче тестовый исходник и измененные файлы для поддержки tn-kernel

Код
typedef struct {
    void*  buff;
    size_t len;
    int    flags;
}Sitem;

#define QUE_SIZE 4

#ifndef USE_MBOX
    TN_FMP pool;
    u32 pool_mem[ sizeof( Sitem ) * ( QUE_SIZE + 2 ) / 4 ];

    static TN_DQUE que_std;
    static void* que_std_fifo[ QUE_SIZE ];
#else
    static TN_MBOX que_mb;
    static Sitem que_mb_fifo[ QUE_SIZE ];
#endif

//------------------------------------------------------------------------------
void task_recv_func(void * par)
{
    while( true )
    {
#ifndef USE_MBOX
        Sitem* msg;
        int result = tn_queue_receive( &que_std, (void**)&msg, TN_WAIT_INFINITE );
        ASSERT( result == TERR_NO_ERR );
        ASSERT( msg->buff == (void*)0x12345678 );
        
        result = tn_fmem_release( &pool, msg );
        ASSERT( result == TERR_NO_ERR );
#else
        Sitem msg;
        int result = tn_mbox_receive( &que_mb,(void**)&msg, TN_WAIT_INFINITE );
        ASSERT( result == TERR_NO_ERR );
        ASSERT( msg.buff == (void*)0x12345678 );
#endif
    }
}

//------------------------------------------------------------------------------
void task_send_func( void* par )                    
{
    while( true )
    {
#ifndef USE_MBOX        
        Sitem* msg;
        int result = tn_fmem_get_polling( &pool, (void**)&msg );
        ASSERT( result == TERR_NO_ERR );

        msg->buff = (void*)0x12345678;
        msg->len = cnt++;
        msg->flags = 0xAA55AA55;
        result = tn_queue_send( &que_std, (void**)msg, TN_WAIT_INFINITE );
        ASSERT( result == TERR_NO_ERR );
#else
        Sitem msg;
        msg.buff = (void*)0x12345678;
        msg.len = cnt++;
        msg.flags = 0xAA55AA55;
        
        int result = tn_mbox_send( &que_mb,(void**)&msg, TN_WAIT_INFINITE );
        ASSERT( result == TERR_NO_ERR );
#endif
        SSP_DBG_PIN_INV;
    }
}

//------------------------------------------------------------------------------
void app_mb_init( void )
{
    int result;
#ifndef USE_MBOX    
    result = tn_queue_create( &que_std,(void**)que_std_fifo, QUE_SIZE );
    ASSERT( result == TERR_NO_ERR );

    result = tn_fmem_create( &pool, pool_mem, sizeof( Sitem ), QUE_SIZE + 2 );
    ASSERT( result == TERR_NO_ERR );
#else
    result = tn_mbox_create( &que_mb,(void**)que_mb_fifo, sizeof( Sitem ), QUE_SIZE  );
    ASSERT( result == TERR_NO_ERR );
#endif
    
    TASK_CREATE( task_send, task_send_func, 8, 100, NULL, TASK_START );
    TASK_CREATE( task_recv, task_recv_func, 9, 100, NULL, TASK_START );
    TASK_CREATE( task_prfm, task_prfm_func, 7, 100, NULL, TASK_START );
}
megajohn
14 скачиваний, 0 камментов

Надеюсь, что хоть идею донёс до вас ?!
megajohn
маленько накосячил, исходники корректно работают если приоритет task_send больше task_recv
для корректной работы во всех ситуациях нужно использовать подправленный


P.S. to WebMaster. может разрешите загружать *.c (и наверное соответсвующие *.cpp *.h *.hpp ) ? Неудачная загрузка. Вам запрещено загружать такой тип файлов
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.