I've got one question about how the cpu consumption is calculated.
Bellow are two programs that do the same thing, play stuff to the soundcard.
The first uses a blocking write, the second a nonblocking one with a select.
The select does not block (if it did, the cpu consumption is reported to
be the same than the first method, both by ps and top). It does an
usleep(10*1000) if there is no space left in the audio buffers.
My question is : why does the first get 5% of cpu consumption reported
by both ps and top when the second gets only 0.1% ? They both do the same
calculations, so it should be equal, nope ? Is it related to the kernel
or just the ps and top programs ? (Is it only a problem ?)
Thank you by advance,
Sed.
------------------------------
- first program
------------------------------
/* first methode : blocking write. */
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/soundcard.h>
#include <math.h>
int open_audio(void)
{
int fd;
int play_precision=16;
int play_stereo=0;
int play_sample_rate=44100;
if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
if (errno == EBUSY) {
fprintf(stderr, "Audio device busy!\n");
return -1;
} else {
perror("Can't open /dev/dsp for writing");
return -1;
}
}
if(ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
fprintf(stderr, "config of samplesize failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
fprintf(stderr, "config of stereo failed");
close(fd);
return -1;
}
if (ioctl(fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
fprintf(stderr, "config of speed failed");
close(fd);
return -1;
}
return fd;
}
void use_cpu(short *buf)
{
static unsigned int j;
int i;
for (i=0; i<2048; i++) {
buf[i]=cos((float)j*2.*M_PI/(44100./440.))*30000.;
j++;
}
}
int main(void)
{
char buf[4096];
int fd=open_audio();
if (fd==-1)
return -1;
while(1) {
use_cpu((short *)buf);
if (write(fd, buf, 4096)==-1) {
perror("write");
close(fd);
return -1;
}
}
return 0;
}
------------------------------
- second program
------------------------------
/* second method : nonblocking write with a usleep (note that doing a blocking select won't change anything to the first method, so unblocking select must be used) */
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/soundcard.h>
#include <math.h>
int open_audio(void)
{
int flags;
int fd;
int play_precision=16;
int play_stereo=0;
int play_sample_rate=44100;
if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
if (errno == EBUSY) {
fprintf(stderr, "Audio device busy!\n");
return -1;
} else {
perror("Can't open /dev/dsp for writing");
return -1;
}
}
/* let's unblock the sound */
if ((flags = fcntl(fd,F_GETFL,0)) == -1) {
fprintf(stderr, "fcntl F_GETFL on /dev/audio failed");
close(fd);
return -1;
}
flags |= O_NDELAY;
if (fcntl(fd, F_SETFL, flags) == -1) {
fprintf(stderr, "fcntl F_SETFL on /dev/audio failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1) {
fprintf(stderr, "config of samplesize failed");
close(fd);
return -1;
}
if(ioctl(fd, SNDCTL_DSP_STEREO, &play_stereo) == -1) {
fprintf(stderr, "config of stereo failed");
close(fd);
return -1;
}
if (ioctl(fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1) {
fprintf(stderr, "config of speed failed");
close(fd);
return -1;
}
return fd;
}
void use_cpu(short *buf)
{
static unsigned int j;
int i;
for (i=0; i<2048; i++) {
buf[i]=cos((float)j*2.*M_PI/(44100./440.))*30000.;
j++;
}
}
int card_ready(int fd)
{
fd_set r, w, e;
struct timeval t;
FD_ZERO(&r);
FD_ZERO(&w);
FD_ZERO(&e);
t.tv_sec=0;
t.tv_usec=0;
FD_SET(fd, &w);
/* it's important not to block on the select, otherwise, cpu consumption is not changed */
if (select(FD_SETSIZE, &r, &w, &e, &t)==-1)
perror("select");
return FD_ISSET(fd, &w);
}
int main(void)
{
char buf[4096];
int fd=open_audio();
if (fd==-1)
return -1;
while(1) {
use_cpu((short *)buf);
/* wait for space available on the soundcard (as you see, we specifically usleep, we don't block on the select) */
while (!card_ready(fd))
usleep(10*1000);
if (write(fd, buf, 4096)==-1) {
perror("write");
close(fd);
return -1;
}
}
return 0;
}
---------------------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/