[linux-audio-dev] oh well, so much for mlock/mmap

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] oh well, so much for mlock/mmap
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: Wed Apr 05 2000 - 01:16:29 EEST


I wrote two test programs (see below). One of them uses mlock/mmap to
step through 24 files, locking their data into RAM in 256kB chunks.
The other uses pread(2) to copy data into an mlocked buffer.

The mmap/mlock version takes 3 times as long as the pread version.

Oh well. Back to the beginning again. There was I feeling so great
that we could use the VM system this way.

--p

--------- mmtest.c --------------------

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <asm/page.h>
#include <asm/msr.h>

#define CYCLES_PER_MSEC 450000.0f
#define LOCKDOWN_BYTES PAGE_SIZE * 32
#define NTRACKS 24
#define DIRECTORY "/tape/24.ardour"

typedef struct {
    int fd;
    size_t file_size;
    char *mmap_buffer;
    size_t mlock_start;
    size_t mlock_end;
} track_t;

int
track_setup (track_t *t, char *path)

{
        struct stat statbuf;

        if ((t->fd = open (path, O_RDWR)) < 0) {
                fprintf (stderr, "can't open file %s\n", path);
                return -1;
        }

        fstat (t->fd, &statbuf);
        t->file_size = statbuf.st_size;

        t->mmap_buffer = (char *) mmap (0, t->file_size,
                                        PROT_READ|PROT_WRITE, MAP_SHARED,
                                        t->fd, 0);

        if (t->mmap_buffer == (char *) MAP_FAILED) {
                printf ("cannot map (%s)\n", strerror (errno));
                return -1;
        }

        t->mlock_start = 0;
        t->mlock_end = LOCKDOWN_BYTES * 2;
        if (mlock (t->mmap_buffer, t->mlock_end)) {
                fprintf (stderr, "%d: cannot do initial mlock (%s)\n",
                         t->fd, strerror (errno));
                return -1;
        }
                         

        return 0;
}

int
track_shift (track_t *t)

{
        unsigned long then, now;

        if (munmap (t->mmap_buffer + t->mlock_start,
                    LOCKDOWN_BYTES)) {
                fprintf (stderr, "%d: cannot unmap (%s)\n",
                         t->fd, strerror (errno));
                return -1;
        }
        
// rdtscl (then);
        if (mlock (t->mmap_buffer + t->mlock_end,
                   LOCKDOWN_BYTES)) {
                fprintf (stderr, "%d: cannot mlock (%s)\n",
                         t->fd, strerror (errno));
                return -1;
        }
// rdtscl (now);
// printf ("%d: %u .. %u took %.3f msecs\n",
// t->fd,
// t->mlock_end,
// t->mlock_end+LOCKDOWN_BYTES-1,
// (float) (now - then) / CYCLES_PER_MSEC);
        
        t->mlock_start += LOCKDOWN_BYTES;
        t->mlock_end += LOCKDOWN_BYTES;

        if (t->fd == 5) {
                printf ("%d: end @ %u of %u\n",
                        t->fd,
                        t->mlock_end,
                        t->file_size);
        }

        return 0;
}

int
main (int argc, char *argv[])

{
        unsigned long then, now;
        track_t tracks[NTRACKS];
        int i;
        int ok_to_continue;

        for (i = 0; i < NTRACKS; i++) {
                char pathbuf[32];

                sprintf (pathbuf, "%s/%d.0", DIRECTORY, i+1);

                if (track_setup (&tracks[i], pathbuf)) {
                        fprintf (stderr, "cannot set up track %d\n", i);
                        return 1;
                }
        }

        ok_to_continue = 1;

        while (ok_to_continue) {
                rdtscl (then);
                for (i = 0; i < NTRACKS; i++) {
                        if (track_shift (&tracks[i])) {
                                ok_to_continue = 0;
                                break;
                        }
                }
                rdtscl (now);
                printf ("***** all tracks took %.3f msecs\n",
                        (float) (now - then) / CYCLES_PER_MSEC);
        }

        return 0;
}

------- readtest.c ---------------------

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <asm/page.h>
#include <asm/msr.h>

#define CYCLES_PER_MSEC 450000.0f
#define LOCKDOWN_BYTES PAGE_SIZE * 32
#define NTRACKS 24
#define DIRECTORY "/tape/24.ardour"

typedef struct {
    int fd;
    size_t file_size;
    size_t position;
    char *buf;
} track_t;

int
track_setup (track_t *t, char *path)

{
        struct stat statbuf;

        if ((t->fd = open (path, O_RDWR)) < 0) {
                fprintf (stderr, "can't open file %s\n", path);
                return -1;
        }

        fstat (t->fd, &statbuf);
        t->file_size = statbuf.st_size;
        t->buf = (char *) malloc (LOCKDOWN_BYTES);

        if (mlock (t->buf, LOCKDOWN_BYTES)) {
                fprintf (stderr, "cannot lock down buffer %d (%s)\n",
                         t->fd, strerror (errno));
                return -1;
        }

        t->position = 0;

        return 0;
}

int
track_shift (track_t *t)

{
        unsigned long then, now;

        if (pread (t->fd, t->buf, LOCKDOWN_BYTES, t->position) !=
            LOCKDOWN_BYTES) {
                fprintf (stderr, "%d: read failed (%s)\n",
                         t->fd, strerror (errno));
        }

        t->position += LOCKDOWN_BYTES;
        return 0;
}

int
main (int argc, char *argv[])

{
        unsigned long then, now;
        track_t tracks[NTRACKS];
        int i;
        int ok_to_continue;

        for (i = 0; i < NTRACKS; i++) {
                char pathbuf[32];

                sprintf (pathbuf, "%s/%d.0", DIRECTORY, i+1);

                if (track_setup (&tracks[i], pathbuf)) {
                        fprintf (stderr, "cannot set up track %d\n", i);
                        return 1;
                }
        }

        ok_to_continue = 1;

        while (ok_to_continue) {
                rdtscl (then);
                for (i = 0; i < NTRACKS; i++) {
                        if (track_shift (&tracks[i])) {
                                ok_to_continue = 0;
                                break;
                        }
                }
                rdtscl (now);
                printf ("***** all tracks took %.3f msecs\n",
                        (float) (now - then) / CYCLES_PER_MSEC);
        }

        return 0;
}


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Wed Apr 05 2000 - 01:04:18 EEST