New compile_cdrskin.sh option -o_direct (Linux only)
This commit is contained in:
parent
677b007100
commit
738b83ac03
@ -25,6 +25,10 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif /* Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
#include "cdrfifo.h"
|
#include "cdrfifo.h"
|
||||||
|
|
||||||
|
|
||||||
@ -174,9 +178,18 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
|||||||
o->follow_up_fd_idx= -1;
|
o->follow_up_fd_idx= -1;
|
||||||
o->next= o->prev= NULL;
|
o->next= o->prev= NULL;
|
||||||
o->chain_idx= 0;
|
o->chain_idx= 0;
|
||||||
|
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
o->buffer= mmap(NULL, (size_t) buffer_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
|
||||||
|
if(o->buffer == MAP_FAILED)
|
||||||
|
goto failed;
|
||||||
|
#else
|
||||||
o->buffer= TSOB_FELD(char,buffer_size);
|
o->buffer= TSOB_FELD(char,buffer_size);
|
||||||
if(o->buffer==NULL)
|
if(o->buffer==NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
#endif /* Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
failed:;
|
failed:;
|
||||||
Cdrfifo_destroy(ff,0);
|
Cdrfifo_destroy(ff,0);
|
||||||
@ -226,8 +239,14 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
|
|||||||
|
|
||||||
if(o->iso_fs_descr!=NULL)
|
if(o->iso_fs_descr!=NULL)
|
||||||
free((char *) o->iso_fs_descr);
|
free((char *) o->iso_fs_descr);
|
||||||
|
|
||||||
if(o->buffer!=NULL)
|
if(o->buffer!=NULL)
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
munmap(o->buffer, o->buffer_size);
|
||||||
|
#else
|
||||||
free((char *) o->buffer);
|
free((char *) o->buffer);
|
||||||
|
#endif /* Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
free((char *) o);
|
free((char *) o);
|
||||||
(*ff)= NULL;
|
(*ff)= NULL;
|
||||||
return(1);
|
return(1);
|
||||||
@ -659,6 +678,49 @@ return: <0 = error , 0 = idle , 1 = did some work
|
|||||||
after_write:;
|
after_write:;
|
||||||
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
||||||
can_read= o->buffer_size - o->write_idx;
|
can_read= o->buffer_size - o->write_idx;
|
||||||
|
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
|
||||||
|
/* ts A91115
|
||||||
|
This chunksize must be aligned to filesystem blocksize.
|
||||||
|
One might try to inquire the block size behind o->source_fd, but since
|
||||||
|
O_DIRECT is a dirty hack anyway, i just guess that 64 KiB is divisible
|
||||||
|
by any existing block size on Linux.
|
||||||
|
*/
|
||||||
|
#define Cdrfifo_o_direct_chunK 65536
|
||||||
|
|
||||||
|
if(o->write_idx < o->read_idx && o->write_idx + can_read > o->read_idx)
|
||||||
|
can_read= o->read_idx - o->write_idx;
|
||||||
|
if(o->fd_in_limit>=0.0)
|
||||||
|
if(can_read > o->fd_in_limit - o->fd_in_counter)
|
||||||
|
can_read= o->fd_in_limit - o->fd_in_counter;
|
||||||
|
/* Make sure to read with properly aligned size */
|
||||||
|
if(can_read > Cdrfifo_o_direct_chunK)
|
||||||
|
can_read= Cdrfifo_o_direct_chunK;
|
||||||
|
else if(can_read < Cdrfifo_o_direct_chunK)
|
||||||
|
can_read= -1;
|
||||||
|
ret= 0;
|
||||||
|
if(can_read>0)
|
||||||
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
|
if(can_read < 0) {
|
||||||
|
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
||||||
|
if(can_write <= 0 && o->dest_fd >= 0) {
|
||||||
|
fd_set rds,wts,exs;
|
||||||
|
struct timeval wt;
|
||||||
|
|
||||||
|
FD_ZERO(&rds);
|
||||||
|
FD_ZERO(&wts);
|
||||||
|
FD_ZERO(&exs);
|
||||||
|
FD_SET((o->dest_fd),&wts);
|
||||||
|
wt.tv_sec= 0;
|
||||||
|
wt.tv_usec= 10000;
|
||||||
|
select(o->dest_fd + 1,&rds, &wts, &exs, &wt);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
|
||||||
|
#else /* Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
if(can_read>o->chunk_size)
|
if(can_read>o->chunk_size)
|
||||||
can_read= o->chunk_size;
|
can_read= o->chunk_size;
|
||||||
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
||||||
@ -669,6 +731,9 @@ after_write:;
|
|||||||
ret= 0;
|
ret= 0;
|
||||||
if(can_read>0)
|
if(can_read>0)
|
||||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
|
|
||||||
|
#endif /* ! Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
|
|
||||||
/* >>> handle input error */;
|
/* >>> handle input error */;
|
||||||
|
@ -339,6 +339,23 @@ or
|
|||||||
/** Verbosity level for fifo debugging */
|
/** Verbosity level for fifo debugging */
|
||||||
#define Cdrskin_verbose_debug_fifO 4
|
#define Cdrskin_verbose_debug_fifO 4
|
||||||
|
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
/* Linux 2.6.18:
|
||||||
|
This can avoid low write speed via USB with 32 KB SCSI write chunks.
|
||||||
|
64 KB write chunking is 20% more effective, though, and this size is
|
||||||
|
not in need for O_DIRECT.
|
||||||
|
Strange: Vanilla read() brings USB 32 KB WRITE down from 11x to 7.5x.
|
||||||
|
Throughput from /dev/zero to /dev/null is 230x. The disk delivers 56x.
|
||||||
|
Clearly Linux USB has a problem with 32 KB chunks. read() without O_DIRECT
|
||||||
|
makes it worse.
|
||||||
|
cdrecord and growisofs bring 11x. At least growisofs uses O_DIRECT for its
|
||||||
|
fifo input.
|
||||||
|
*/
|
||||||
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
# endif
|
||||||
|
#endif /* Cdrskin_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1388,7 +1405,11 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
|
|||||||
if(is_wav==-3)
|
if(is_wav==-3)
|
||||||
return(0);
|
return(0);
|
||||||
if(is_wav==0)
|
if(is_wav==0)
|
||||||
|
#ifdef Cdrskin_read_o_direcT
|
||||||
|
*fd= open64(track->source_path, O_RDONLY | O_DIRECT);
|
||||||
|
#else
|
||||||
*fd= open(track->source_path, O_RDONLY);
|
*fd= open(track->source_path, O_RDONLY);
|
||||||
|
#endif
|
||||||
if(*fd==-1) {
|
if(*fd==-1) {
|
||||||
fprintf(stderr,"cdrskin: failed to open source address '%s'\n",
|
fprintf(stderr,"cdrskin: failed to open source address '%s'\n",
|
||||||
track->source_path);
|
track->source_path);
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2009.11.15.115923"
|
#define Cdrskin_timestamP "2009.11.15.152541"
|
||||||
|
@ -55,6 +55,9 @@ do
|
|||||||
elif test "$i" = "-no_largefile"
|
elif test "$i" = "-no_largefile"
|
||||||
then
|
then
|
||||||
largefile_opts=
|
largefile_opts=
|
||||||
|
elif test "$i" = "-o_direct"
|
||||||
|
then
|
||||||
|
def_opts="$def_opts -DCdrskin_read_o_direcT"
|
||||||
elif test "$i" = "-do_not_compile_cdrskin"
|
elif test "$i" = "-do_not_compile_cdrskin"
|
||||||
then
|
then
|
||||||
compile_cdrskin=0
|
compile_cdrskin=0
|
||||||
@ -77,6 +80,7 @@ do
|
|||||||
echo " -compile_dewav compile program test/dewav without libburn."
|
echo " -compile_dewav compile program test/dewav without libburn."
|
||||||
echo " -libburn_0_7_2 set macro to match libburn-0.7.2"
|
echo " -libburn_0_7_2 set macro to match libburn-0.7.2"
|
||||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||||
|
echo " -o_direct use open(O_DIRECT) on fifo input (Linux only)."
|
||||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||||
|
Loading…
Reference in New Issue
Block a user