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;
}
This archive was generated by hypermail 2b28 : Wed Apr 05 2000 - 01:04:18 EEST