diff --git a/library/changes b/library/changes index b010975..9037cd4 100644 --- a/library/changes +++ b/library/changes @@ -1,3 +1,6 @@ +- I/O buffers allocated are now aligned according to the CPU cache line size, + if the operating system can supply that detailed information. + - unsetenv() now returns a status value. - Corrected the function prototype for wcspbrk(). diff --git a/library/stdio_file_init.c b/library/stdio_file_init.c index 5f5a5fc..8e51c56 100644 --- a/library/stdio_file_init.c +++ b/library/stdio_file_init.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_file_init.c,v 1.12 2006-11-16 14:39:23 obarthel Exp $ + * $Id: stdio_file_init.c,v 1.13 2008-09-04 12:07:58 obarthel Exp $ * * :ts=4 * @@ -76,6 +76,11 @@ struct WBStartup * NOCOMMON __WBenchMsg; /****************************************************************************/ +/* CPU cache line size; used to align I/O buffers for best performance. */ +ULONG __cache_line_size = 32; + +/****************************************************************************/ + FILE_DESTRUCTOR(workbench_exit) { ENTER(); @@ -215,6 +220,24 @@ FILE_CONSTRUCTOR(stdio_file_init) ENTER(); + /* Figure out the proper address alignment for the memory we are + going to use for disk I/O. The default is 32 bytes, which should + be OK for most cases. If possible, ask the operating system for + its preferred alignment size. */ + #if defined(__amigaos4__) + { + if(SysBase->lib_Version >= 50) + { + uint32 physical_alignment = 0; + + GetCPUInfoTags(GCIT_CacheLineSize,&physical_alignment,TAG_DONE); + + if(__cache_line_size < physical_alignment) + __cache_line_size = physical_alignment; + } + } + #endif /* __amigaos4__ */ + /* If we were invoked from Workbench, set up the standard I/O streams. */ if(__WBenchMsg != NULL) { @@ -255,7 +278,7 @@ FILE_CONSTRUCTOR(stdio_file_init) PROFILE_ON(); /* Allocate a little more memory than necessary. */ - buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1)); + buffer = malloc(BUFSIZ + (__cache_line_size - 1)); if(buffer == NULL) goto out; @@ -300,7 +323,7 @@ FILE_CONSTRUCTOR(stdio_file_init) #endif /* __THREAD_SAFE */ /* Align the buffer start address to a cache line boundary. */ - aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1)); + aligned_buffer = (char *)((ULONG)(buffer + (__cache_line_size-1)) & ~(__cache_line_size-1)); __initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags,fd_lock); diff --git a/library/stdio_grow_file.c b/library/stdio_grow_file.c index 1f45623..2a3eedd 100644 --- a/library/stdio_grow_file.c +++ b/library/stdio_grow_file.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_grow_file.c,v 1.7 2006-11-16 14:39:23 obarthel Exp $ + * $Id: stdio_grow_file.c,v 1.8 2008-09-04 12:07:58 obarthel Exp $ * * :ts=4 * @@ -90,7 +90,7 @@ __grow_file_size(struct fd * fd,int num_bytes) /* Allocate a little more memory than required to allow for * the buffer to be aligned to a cache line boundary. */ - buffer = malloc((size_t)buffer_size + (CACHE_LINE_SIZE-1)); + buffer = malloc((size_t)buffer_size + (__cache_line_size-1)); if(buffer == NULL) { SHOWMSG("not enough memory for write buffer"); @@ -100,7 +100,7 @@ __grow_file_size(struct fd * fd,int num_bytes) } /* Align the buffer to a cache line boundary. */ - aligned_buffer = (unsigned char *)(((ULONG)(buffer + (CACHE_LINE_SIZE-1))) & ~(CACHE_LINE_SIZE-1)); + aligned_buffer = (unsigned char *)(((ULONG)(buffer + (__cache_line_size-1))) & ~(__cache_line_size-1)); memset(aligned_buffer,0,(size_t)buffer_size); diff --git a/library/stdio_headers.h b/library/stdio_headers.h index c836059..df1e7a1 100644 --- a/library/stdio_headers.h +++ b/library/stdio_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_headers.h,v 1.30 2006-11-16 14:39:23 obarthel Exp $ + * $Id: stdio_headers.h,v 1.31 2008-09-04 12:07:58 obarthel Exp $ * * :ts=4 * @@ -156,18 +156,6 @@ struct iob; /****************************************************************************/ -/* CPU cache line size; used for alignment purposes with some data structures. - This should be determined dynamically rather than preset here. For the - 68040/68060 the cache line size is 16 bytes, for the PowerPC G4 it's - 32 bytes and 128 bytes (gross!) for the PowerPC G5. */ -#if defined(__PPC__) -#define CACHE_LINE_SIZE 32UL -#else -#define CACHE_LINE_SIZE 16UL -#endif /* __PPC__ */ - -/****************************************************************************/ - /* The directory entry type a socket is identified with (in a FileInfoBlock). */ #define ST_SOCKET (31082002) @@ -399,6 +387,11 @@ extern BOOL NOCOMMON __no_standard_io; /****************************************************************************/ +/* CPU cache line size; used to align I/O buffers for best performance. */ +extern ULONG __cache_line_size; + +/****************************************************************************/ + /*extern int __iob_write_buffer_is_full(struct iob * file);*/ #define __iob_write_buffer_is_full(file) \ diff --git a/library/stdio_openiob.c b/library/stdio_openiob.c index 19c7c82..ec5e5f2 100644 --- a/library/stdio_openiob.c +++ b/library/stdio_openiob.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_openiob.c,v 1.14 2006-01-08 12:04:24 obarthel Exp $ + * $Id: stdio_openiob.c,v 1.15 2008-09-04 12:07:58 obarthel Exp $ * * :ts=4 * @@ -133,7 +133,7 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot SHOWMSG("allocating file buffer"); /* Allocate a little more memory than necessary. */ - buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1)); + buffer = malloc(BUFSIZ + (__cache_line_size-1)); if(buffer == NULL) { SHOWMSG("that didn't work"); @@ -143,7 +143,7 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot } /* Align the buffer start address to a cache line boundary. */ - aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1)); + aligned_buffer = (char *)((ULONG)(buffer + (__cache_line_size-1)) & ~(__cache_line_size-1)); if(file_descriptor < 0) { diff --git a/library/stdio_setvbuf.c b/library/stdio_setvbuf.c index c8afaaf..785fdbb 100644 --- a/library/stdio_setvbuf.c +++ b/library/stdio_setvbuf.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_setvbuf.c,v 1.10 2006-09-22 09:02:51 obarthel Exp $ + * $Id: stdio_setvbuf.c,v 1.11 2008-09-04 12:07:58 obarthel Exp $ * * :ts=4 * @@ -123,7 +123,7 @@ setvbuf(FILE *stream,char *buf,int bufmode,size_t size) if(size > 0 && buf == NULL) { /* Allocate a little more memory than necessary. */ - new_buffer = malloc(size + (CACHE_LINE_SIZE-1)); + new_buffer = malloc(size + (__cache_line_size-1)); if(new_buffer == NULL) { __set_errno(ENOBUFS); @@ -170,7 +170,7 @@ setvbuf(FILE *stream,char *buf,int bufmode,size_t size) file->iob_CustomBuffer = new_buffer; /* Align the buffer start address to a cache line boundary. */ - new_buffer = (char *)((ULONG)(new_buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1)); + new_buffer = (char *)((ULONG)(new_buffer + (__cache_line_size-1)) & ~(__cache_line_size-1)); } }