Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > из "с" в "с++"


Автор: box 9.9.2013, 15:14
всем привет!
народ , помогите переделать функцию из с в с++ совместимую
Код

static inline void
pkt_copy(const void *_src, void *_dst, int l)
{
    const uint64_t *src = _src;
    uint64_t *dst = _dst;
#define likely(x)       __builtin_expect(!!(x), 1)
#define unlikely(x)       __builtin_expect(!!(x), 0)
    if (unlikely(l >= 1024)) {
        bcopy(src, dst, l);
        return;
    }
    for (; l > 0; l-=64) {
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
        *dst++ = *src++;
    }
}

просто когда компилю g++ сыпятся ошибки :

./nm_util.h:170:18: error: cannot initialize a variable of type 'const uint64_t *' (aka 'const unsigned long *') with an lvalue of type 'const void *'
        const uint64_t *src = _src;
                        ^     ~~~~
./nm_util.h:171:12: error: cannot initialize a variable of type 'uint64_t *' (aka 'unsigned long *') with an lvalue of type 'void *'
        uint64_t *dst = _dst;

Автор: kuzulis 9.9.2013, 17:10
#include <cstdint>

Ах, сорри, скорее всего надо просто кастить, читай про reinterpret_cast и пр. касты.

Автор: feodorv 9.9.2013, 17:29
C++ более требовательный к преобразованию типов, и по умолчанию void* не сводится к long*.
Можно в старом стиле просто написать:
Код

    const uint64_t *src = (uint64_t *) _src;

либо более культурно воспользоваться http://ru.wikipedia.org/wiki/%CF%F0%E8%E2%E5%E4%E5%ED%E8%E5_%F2%E8%EF%E0#static_cast.

Автор: box 9.9.2013, 18:29
спасибо
а еще вопросик , там как я понимаю идет копирование данных из структуры в структуру , как унгичтожить данные по адресу src ?

Автор: bsa 9.9.2013, 19:34
box, если не секрет, а чем memcpy не подошел?
Цитата(box @  9.9.2013,  19:29 Найти цитируемый пост)
 как унгичтожить данные по адресу src ?
Что ты понимаешь под "уничтожить"? Освободить память или записать мусор? Если первое, то free().

Автор: feodorv 9.9.2013, 19:38
Цитата(box @  9.9.2013,  19:29 Найти цитируемый пост)
как унгичтожить данные по адресу src ? 

Очень мало информации Вы предоставили для ответа.
  • что происходит с данными по адресу dst?
  • была ли аллокирована память под src?
  • что сбой представляют данные scr?
  • что Вы вкладываете в термин "уничтожить"?

Автор: box 9.9.2013, 19:52
дело имею с кольцевыми буферами netmap , напрямую освобождать память не получается free(rxring) 
<jemalloc>: /usr/src/lib/libc/../../contrib/jemalloc/include/jemalloc/internal/arena.h:949: Failed assertion: "arena_mapbits_allocated_get(chunk, pageind) != 0"
а если не освобождать память то буфер сетевой карты очень быстро переполняется...
надо не заметно удалить все данные из слота ринг буфера 
даже и не знаю куда копать ...

Добавлено через 12 минут и 32 секунды
смотрите комент:
Код


static int
process_rings(struct netmap_ring *rxring, struct netmap_ring *txring,
          u_int limit, const char *msg, struct my_ring *src, struct my_ring *dst)
{
    u_int j, k, m = 0;

    /* print a warning if any of the ring flags is set (e.g. NM_REINIT) */
    if (rxring->flags || txring->flags)
        D("%s rxflags %x txflags %x",
            msg, rxring->flags, txring->flags);
    j = rxring->cur; /* RX */
    k = txring->cur; /* TX */
    if (rxring->avail < limit)
        limit = rxring->avail;
    if (txring->avail < limit)
        limit = txring->avail;
    m = limit;
    while (limit-- > 0) {
        struct netmap_slot *rs = &rxring->slot[j];
        struct netmap_slot *ts = &txring->slot[k];
        
        char *rxbuf = NETMAP_BUF(rxring, rs->buf_idx);
        char *txbuf = NETMAP_BUF(txring, ts->buf_idx);

        /* swap packets */
        if (ts->buf_idx < 2 || rs->buf_idx < 2) {D("wrong index rx[%d] = %d  -> tx[%d] = %d", j, rs->buf_idx, k, ts->buf_idx);sleep(2);}

        /* copy the packet length. */
        if (rs->len < 14 || rs->len > 2048)
            D("wrong len %d rx[%d] -> tx[%d]", rs->len, j, k);
        else if (verbose > 1)
            D("%s send len %d rx[%d] -> tx[%d]", msg, rs->len, j, k);
        ts->len = rs->len;

                int res = 1;
                res = check_(rxbuf, rs->len);//тут проводим проверку пакета и если возвращаем 1 то пускаем пакет по назначению а если 0 то дропаем его не посылая в стек ядра 

                 if(res == 1)
                 {
        pkt_copy(rxbuf, txbuf, ts->len);
                  }else{
/*тут надо освободить память */
                  }

        j = NETMAP_RING_NEXT(rxring, j);
        k = NETMAP_RING_NEXT(txring, k);
    }
    rxring->avail -= m;
    txring->avail -= m;
    rxring->cur = j;
    txring->cur = k;

    return (m);
}



/* move packts from src to destination */
static int
move(struct my_ring *src, struct my_ring *dst, u_int limit)
{
    struct netmap_ring *txring, *rxring;
    u_int m = 0, si = src->begin, di = dst->begin;
    const char *msg = (src->queueid & NETMAP_SW_RING) ? "host->net" : "net->host";

    while (si < src->end && di < dst->end) {
        rxring = NETMAP_RXRING(src->nifp, si);
        txring = NETMAP_TXRING(dst->nifp, di);
        ND("txring %p rxring %p", txring, rxring);
        if (rxring->avail == 0) {
            si++;
            continue;
        }
        if (txring->avail == 0) {
            di++;
            continue;
        }
        m += process_rings(rxring, txring, limit, msg, src, dst);
    }

    return (m);
}


Автор: akizelokro 9.9.2013, 23:09
Код

static inline void
pkt_copy(const void *_src, void *_dst, int l)

написать в одну строку. это раз.

И вообще, код забавный. Лучше это не переделывать

Автор: feodorv 10.9.2013, 00:32
Цитата(box @  9.9.2013,  20:52 Найти цитируемый пост)
напрямую освобождать память не получается free(rxring) 

Ну, если не Вы лично эту память заказывали, то вполне понятно.

С NETMAP, увы, не знаком. Поверхностное чтение http://habrahabr.ru/post/183832/ показала, что эти буферы не нуждаются в непосредственном высвобождении, так как созданы в разделяемой памяти. Тем не менее, как-то нужно дать знать драйверу, что этот буфер больше не используется. Как - не знаю.

Этот вопрос лучше всего задать в http://forum.vingrad.ru/forum/c-c++network.html разделе форума.

Автор: box 10.9.2013, 01:47
всем спасибо , вопрос решен!
Код

.....
memset(rxbuf, 0, rs->len);
pkt_copy(rxbuf, txbuf, ts->len);    
.....

немножко через опу но работает , не виснет от переполнения буфера.
странно , но иоцтл не работает почему то :
Код

        ioctl(src->fd, NIOCRXSYNC, NULL);

Автор: volatile 10.9.2013, 20:52
Цитата(box @  9.9.2013,  15:14 Найти цитируемый пост)
всем привет!
народ , помогите переделать функцию из с в с++ совместимую

Код

static inline void
pkt_copy(const void *_src, void *_dst, int l)
{
   memcpy (_dst, _src, l);
}
 smile 
так побыстрее и побезопаснее будет,
а то у вас нехорошо, например, длина данных должна быть обязательно кратна 64 байтам, иначе случится что-то очень некрасивое...

Автор: borisbn 11.9.2013, 06:58
> длина данных должна быть обязательно кратна 64 байтам
Из названия ф-ции ИМХО следует, что так оно и д.б.
> так побыстрее
не факт  smile 

Автор: volatile 12.9.2013, 01:46
Цитата(borisbn @  11.9.2013,  06:58 Найти цитируемый пост)
> длина данных должна быть обязательно кратна 64 байтам
Из названия ф-ции ИМХО следует, что так оно и д.б.

pkt_copy - да, тут и ежу ясно что именно 64 байтные блоки должны быть, и никак иначе. как это я не догадался...

И кстати если делать копирование пакетами, то лучше уж передавать размер не в байтах, а кол-во пакетов.
Вот тогда, физически невозможно будет передать нечетное число. (как бы там офигенно ясно функция не называлась  smile )

Цитата(borisbn @  11.9.2013,  06:58 Найти цитируемый пост)
> так побыстрее
не факт   

memcpy - одна из наиболее оптимизированных функций CRT, написана на асме, с применением SSE
впрочем да, не факт.

Автор: ТарасАтавин 16.9.2013, 15:40
Поставь явное приведение типов указателей: 
Код
const uint64_t *src = (const uint64_t *) _src;
uint64_t *dst = (uint64_t *)_dst;
 вместо 
Код
const uint64_t *src =  _src;
uint64_t *dst =_dst;
.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)