Skip to content

Commit

Permalink
Implement mmap support with STORE and RETRIEVE notifications
Browse files Browse the repository at this point in the history
This one doesn't use server side mmap of the fuse device to access the
contents of the client side memory maps.  Instead it uses the STORE
and RETRIEVE notifications for this purpose.
  • Loading branch information
Miklos Szeredi committed Dec 6, 2011
1 parent 37eb730 commit 14a9cff
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ OSSP_PADSP_CFLAGS := $(shell pkg-config --cflags libpulse)
endif

ifeq "$(origin OSSP_PADSP_LDFLAGS)" "undefined"
OSSP_PADSP_LDFLAGS := $(shell pkg-config --libs libpulse)
OSSP_PADSP_LDFLAGS := $(shell pkg-config --libs libpulse) -lpthread
endif

ifeq "$(origin OSSP_ALSAP_CFLAGS)" "undefined"
Expand Down
56 changes: 56 additions & 0 deletions ossp-padsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,58 @@ static ssize_t padsp_open(enum ossp_opcode opcode,
return 0;
}

static void notify_mmap_fill_play(size_t mmap_size, size_t pos, size_t bytes)
{
while (bytes) {
ssize_t ret;
size_t count = min(bytes, mmap_size - pos);
struct ossp_notify event = { .magic = OSSP_NOTIFY_MAGIC,
.opcode = OSSP_NOTIFY_FILL };

ossp_mmap_transfer[PLAY].pos = pos;
ossp_mmap_transfer[PLAY].bytes = count;

ret = write(ossp_notify_fd, &event, sizeof(event));
if (ret != sizeof(event)) {
if (errno != EPIPE)
err_e(-errno, "write to notify_fd failed");

padsp_done();
return;
}
sem_wait(&ossp_mmap_transfer[PLAY].sem);

bytes -= count;
pos = (pos + count) % mmap_size;
}
}

static void notify_mmap_store_rec(size_t mmap_size, size_t pos, size_t bytes)
{
while (bytes) {
ssize_t ret;
size_t count = min(bytes, mmap_size - pos);
struct ossp_notify event = { .magic = OSSP_NOTIFY_MAGIC,
.opcode = OSSP_NOTIFY_STORE };

ossp_mmap_transfer[REC].pos = pos;
ossp_mmap_transfer[REC].bytes = count;

ret = write(ossp_notify_fd, &event, sizeof(event));
if (ret != sizeof(event)) {
if (errno != EPIPE)
err_e(-errno, "write to notify_fd failed");

padsp_done();
return;
}
sem_wait(&ossp_mmap_transfer[REC].sem);

bytes -= count;
pos = (pos + count) % mmap_size;
}
}

static void mmap_fill_pstg(void)
{
struct ring_buf *stg = &mmap_stg[PLAY];
Expand Down Expand Up @@ -812,6 +864,8 @@ static void mmap_fill_pstg(void)
bytes = space;
}

notify_mmap_fill_play(mmap_size, mmap_idx[PLAY] % mmap_size, bytes);

ring_manual_init(&mmap, mmap_map[PLAY], mmap_size,
new_idx % mmap_size, bytes);

Expand Down Expand Up @@ -898,6 +952,8 @@ static void mmap_consume_rstg(void)
space -= todo;
}

notify_mmap_store_rec(mmap_size, fill_idx % mmap_size, ring_bytes(&mmap));

skip:
mmap_idx[REC] = new_idx;
}
Expand Down
13 changes: 5 additions & 8 deletions ossp-slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,21 @@ static const char *usage =
" -c CMD_FD fd to receive commands from osspd\n"
" -n NOTIFY_FD fd to send async notifications to osspd\n"
" -m MMAP_FD fd to use for mmap\n"
" -o MMAP_OFFSET mmap offset\n"
" -s MMAP_SIZE mmap size\n"
" -l LOG_LEVEL set log level\n"
" -t enable log timestamps\n";

char ossp_user_name[OSSP_USER_NAME_LEN];
int ossp_cmd_fd = -1, ossp_notify_fd = -1;
void *ossp_mmap_addr[2];
struct ossp_transfer *ossp_mmap_transfer;

void ossp_slave_init(int argc, char **argv)
{
int have_uid = 0, have_gid = 0;
uid_t uid;
gid_t gid;
int mmap_fd = -1;
off_t mmap_off = 0;
size_t mmap_size = 0;
int opt;
struct passwd *pw, pw_buf;
Expand All @@ -73,9 +72,6 @@ void ossp_slave_init(int argc, char **argv)
case 'm':
mmap_fd = strtol(optarg, NULL, 0);
break;
case 'o':
mmap_off = strtoull(optarg, NULL, 0);
break;
case 's':
mmap_size = strtoul(optarg, NULL, 0);
break;
Expand Down Expand Up @@ -104,18 +100,19 @@ void ossp_slave_init(int argc, char **argv)
if (mmap_fd >= 0) {
void *p;

if (!mmap_off || !mmap_size) {
if (!mmap_size) {
fprintf(stderr, usage);
_exit(1);
}

p = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED,
mmap_fd, mmap_off);
p = mmap(NULL, mmap_size + 2 * sizeof(struct ossp_transfer),
PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, 0);
if (p == MAP_FAILED)
fatal_e(-errno, "mmap failed");

ossp_mmap_addr[PLAY] = p;
ossp_mmap_addr[REC] = p + mmap_size / 2;
ossp_mmap_transfer = p + mmap_size;
close(mmap_fd);
}

Expand Down
1 change: 1 addition & 0 deletions ossp-slave.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
extern char ossp_user_name[OSSP_USER_NAME_LEN];
extern int ossp_cmd_fd, ossp_notify_fd;
extern void *ossp_mmap_addr[2];
extern struct ossp_transfer *ossp_mmap_transfer;

void ossp_slave_init(int argc, char **argv);
int ossp_slave_process_command(int cmd_fd,
Expand Down
9 changes: 9 additions & 0 deletions ossp.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <sys/types.h>
#include <inttypes.h>
#include <semaphore.h>
#include <sys/soundcard.h>

#define OSSP_VERSION "1.3.2"
Expand Down Expand Up @@ -64,10 +65,18 @@ enum ossp_notify_opcode {
OSSP_NOTIFY_POLL,
OSSP_NOTIFY_OBITUARY,
OSSP_NOTIFY_VOLCHG,
OSSP_NOTIFY_FILL,
OSSP_NOTIFY_STORE,

OSSP_NR_NOTIFY_OPCODES,
};

struct ossp_transfer {
sem_t sem;
size_t pos;
size_t bytes;
};

struct ossp_mixer_arg {
int vol[2][2];
};
Expand Down
Loading

0 comments on commit 14a9cff

Please sign in to comment.