LINUX.ORG.RU

падает io_queue_run. ЧЯДНТ?


0

1

код:

    const int pktperslot = SLOT_SIZE / mtu;
    io_context_t ctx = 0;
    struct iocb   iocbs[numslots];
    struct iocb * piocbs[numslots];

    for(int i = 0; i < numslots; ++i) {
        piocbs[i] = iocbs+i;
    }

    int r = io_setup(256, &ctx);
    if (r < 0) {
        qFatal("Failed to setup disk io context: %s", strerror(-r));
        return;
    }
    qint64 count = 0;
    qint64 newcount;
buffer = это кольцевой буфер, побитый на слоты по 2Мб (SLOT_SIZE), а те в свою очередь на пакеты размером в mtu. Отдельный поток быстро ловит пакеты и кладет их в очередь и обновляет packet count
    while(!finish) {
        newcount = count;
        mutex.lock();
        if (cond.wait(&mutex, 100))
            newcount = packet_count;
        mutex.unlock();
        if (newcount == count) continue;
        qDebug("packets available: %lld (%lld)", newcount - count, count);
если набрался полный 2х метровый блок, то мы готовим iocbs под каждый готовый блок, обновляем указатель чтения на колво пакетов под запись. pktperslot = SLOT_SIZE/mtu
        qint64 blks = (newcount - count) / pktperslot;
        if (blks) {
            qint64 start = count / pktperslot % numslots;
            qint64 end = start;
            for(qint64 i = 0; i < blks; ++i) {
                io_prep_pwrite(iocbs+end, 
                               disk,
                               buffer + SLOT_SIZE * end,
                               SLOT_SIZE,
                               (count+i) * SLOT_SIZE);
                io_set_callback(iocbs+end, NULL);
                if(++end >= numslots) end = 0;
            }
            count += blks * pktperslot;
вызываем io_submit. у нас заранее выделен массив iocbs по одному на каждый 2х метровый участов кольцевого буфера.
            qDebug("prepare %lld -- %lld", start, end);
            if (end < start && end) {
                qDebug("submit(1) %lld -- %lld", start, qint64(numslots));
                r = io_submit(ctx, numslots - start, piocbs + start);
                if (r < 0) {
                    qFatal("Failed to setup disk io context: %s", strerror(-r));
                    return;
                }
                qDebug("submit(2) 0 -- %lld", end);
                r = io_submit(ctx, end, piocbs);
                if (r < 0) {
                    qFatal("Failed to setup disk io context: %s", strerror(-r));
                    return;
                }
            } else if (!end) {
                qDebug("submit(3) %lld -- %lld", start, qint64(numslots));
                r = io_submit(ctx, numslots - start, piocbs + start);
                if (r < 0) {
                    qFatal("Failed to setup disk io context: %s", strerror(-r));
                    return;
                }
            } else {
                qDebug("submit(4) %lld -- %lld", start, end);
                r = io_submit(ctx, end - start, piocbs + start);
                if (r < 0) {
                    qFatal("Failed to setup disk io context: %s", strerror(-r));
                    return;
                }
            }
и вот на следующей строке всё падает прямо на первом вызове внутре libaio:
            io_queue_run(ctx);
        }     
    }

ctx инициализован верно, и без ошибок. знаю что написано коряво, но надо победить падение прежде чем улучшать код.

писал с оглядкой на http://www.linuxcertif.com/man/3/io/

почему оно падает? ни одной жалобы в логе на ошибки нету. просто бум и сегфолт

Ответ на: комментарий от joy4eg

так он гад в libaio падает. которая стоковая из бубунты может я что то не так сделал?

ckotinko ☆☆☆ ()
Последнее исправление: ckotinko (всего исправлений: 1)
Ответ на: комментарий от joy4eg

лол, файл был открыт с O_DIRECT, буфер не выровнен на 4кб. и все!

libaio решето.

ckotinko ☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.