mirror of
https://github.com/samba-team/samba.git
synced 2025-08-05 12:22:11 +03:00
Used cachegrind to track down some bottlenecks.
Removed calls to clobber_region when not compiling with developer as they were hiding speed problems. Added fast path to convert_string() when dealing with ascii -> ascii, ucs2-le to ascii and ascii to ucs2-le with values <= 0x7F. This gives a speedup of 22% on my nbench tests. Next I will do this on convert_string_allocate. Jeremy.
This commit is contained in:
@ -150,6 +150,7 @@ void init_iconv(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert string from one encoding to another, making error checking etc
|
* Convert string from one encoding to another, making error checking etc
|
||||||
|
* Slow path version - uses (slow) iconv.
|
||||||
*
|
*
|
||||||
* @param src pointer to source string (multibyte or singlebyte)
|
* @param src pointer to source string (multibyte or singlebyte)
|
||||||
* @param srclen length of the source string in bytes
|
* @param srclen length of the source string in bytes
|
||||||
@ -160,7 +161,8 @@ void init_iconv(void)
|
|||||||
* Ensure the srclen contains the terminating zero.
|
* Ensure the srclen contains the terminating zero.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
size_t convert_string(charset_t from, charset_t to,
|
|
||||||
|
static size_t convert_string_internal(charset_t from, charset_t to,
|
||||||
void const *src, size_t srclen,
|
void const *src, size_t srclen,
|
||||||
void *dest, size_t destlen)
|
void *dest, size_t destlen)
|
||||||
{
|
{
|
||||||
@ -170,18 +172,13 @@ size_t convert_string(charset_t from, charset_t to,
|
|||||||
char* outbuf = (char*)dest;
|
char* outbuf = (char*)dest;
|
||||||
smb_iconv_t descriptor;
|
smb_iconv_t descriptor;
|
||||||
|
|
||||||
if (srclen == (size_t)-1)
|
|
||||||
srclen = strlen(src)+1;
|
|
||||||
if (srclen == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
lazy_initialize_conv();
|
lazy_initialize_conv();
|
||||||
|
|
||||||
descriptor = conv_handles[from][to];
|
descriptor = conv_handles[from][to];
|
||||||
|
|
||||||
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
|
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
|
||||||
if (!conv_silent)
|
if (!conv_silent)
|
||||||
DEBUG(0,("convert_string: Conversion not supported.\n"));
|
DEBUG(0,("convert_string_internal: Conversion not supported.\n"));
|
||||||
goto use_as_is;
|
goto use_as_is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,12 +191,12 @@ size_t convert_string(charset_t from, charset_t to,
|
|||||||
case EINVAL:
|
case EINVAL:
|
||||||
reason="Incomplete multibyte sequence";
|
reason="Incomplete multibyte sequence";
|
||||||
if (!conv_silent)
|
if (!conv_silent)
|
||||||
DEBUG(3,("convert_string: Conversion error: %s(%s)\n",reason,inbuf));
|
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
|
||||||
goto use_as_is;
|
goto use_as_is;
|
||||||
case E2BIG:
|
case E2BIG:
|
||||||
reason="No more room";
|
reason="No more room";
|
||||||
if (!conv_silent)
|
if (!conv_silent)
|
||||||
DEBUG(3, ("convert_string: Required %lu, available %lu\n",
|
DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
|
||||||
(unsigned long)srclen, (unsigned long)destlen));
|
(unsigned long)srclen, (unsigned long)destlen));
|
||||||
/* we are not sure we need srclen bytes,
|
/* we are not sure we need srclen bytes,
|
||||||
may be more, may be less.
|
may be more, may be less.
|
||||||
@ -209,11 +206,11 @@ size_t convert_string(charset_t from, charset_t to,
|
|||||||
case EILSEQ:
|
case EILSEQ:
|
||||||
reason="Illegal multibyte sequence";
|
reason="Illegal multibyte sequence";
|
||||||
if (!conv_silent)
|
if (!conv_silent)
|
||||||
DEBUG(3,("convert_string: Conversion error: %s(%s)\n",reason,inbuf));
|
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
|
||||||
goto use_as_is;
|
goto use_as_is;
|
||||||
default:
|
default:
|
||||||
if (!conv_silent)
|
if (!conv_silent)
|
||||||
DEBUG(0,("convert_string: Conversion error: %s(%s)\n",reason,inbuf));
|
DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* smb_panic(reason); */
|
/* smb_panic(reason); */
|
||||||
@ -231,6 +228,90 @@ size_t convert_string(charset_t from, charset_t to,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert string from one encoding to another, making error checking etc
|
||||||
|
* Fast path version - handles ASCII first.
|
||||||
|
*
|
||||||
|
* @param src pointer to source string (multibyte or singlebyte)
|
||||||
|
* @param srclen length of the source string in bytes
|
||||||
|
* @param dest pointer to destination string (multibyte or singlebyte)
|
||||||
|
* @param destlen maximal length allowed for string
|
||||||
|
* @returns the number of bytes occupied in the destination
|
||||||
|
*
|
||||||
|
* Ensure the srclen contains the terminating zero.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
size_t convert_string(charset_t from, charset_t to,
|
||||||
|
void const *src, size_t srclen,
|
||||||
|
void *dest, size_t destlen)
|
||||||
|
{
|
||||||
|
if (srclen == (size_t)-1) {
|
||||||
|
if (from == CH_UCS2)
|
||||||
|
srclen = strlen_w(src)+2;
|
||||||
|
else
|
||||||
|
srclen = strlen(src)+1;
|
||||||
|
}
|
||||||
|
if (srclen == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (from != CH_UCS2 && to != CH_UCS2) {
|
||||||
|
const unsigned char *p = (const unsigned char *)src;
|
||||||
|
unsigned char *q = (unsigned char *)dest;
|
||||||
|
size_t retval = 0;
|
||||||
|
|
||||||
|
/* If all characters are ascii, fast path here. */
|
||||||
|
while (srclen && destlen) {
|
||||||
|
if (*p <= 0x7f) {
|
||||||
|
*q++ = *p++;
|
||||||
|
srclen--;
|
||||||
|
destlen--;
|
||||||
|
retval++;
|
||||||
|
} else {
|
||||||
|
return retval + convert_string_internal(from, to, p, srclen, q, destlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
} else if (from == CH_UCS2 && to != CH_UCS2) {
|
||||||
|
const unsigned char *p = (const unsigned char *)src;
|
||||||
|
unsigned char *q = (unsigned char *)dest;
|
||||||
|
size_t retval = 0;
|
||||||
|
|
||||||
|
/* If all characters are ascii, fast path here. */
|
||||||
|
while ((srclen >= 2) && destlen) {
|
||||||
|
if (*p <= 0x7f && p[1] == 0) {
|
||||||
|
*q++ = *p;
|
||||||
|
srclen -= 2;
|
||||||
|
p += 2;
|
||||||
|
destlen--;
|
||||||
|
retval++;
|
||||||
|
} else {
|
||||||
|
return retval + convert_string_internal(from, to, p, srclen, q, destlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
} else if (from != CH_UCS2 && to == CH_UCS2) {
|
||||||
|
const unsigned char *p = (const unsigned char *)src;
|
||||||
|
unsigned char *q = (unsigned char *)dest;
|
||||||
|
size_t retval = 0;
|
||||||
|
|
||||||
|
/* If all characters are ascii, fast path here. */
|
||||||
|
while (srclen && (destlen >= 2)) {
|
||||||
|
if (*p <= 0x7F) {
|
||||||
|
*q++ = *p++;
|
||||||
|
*q++ = '\0';
|
||||||
|
srclen--;
|
||||||
|
destlen -= 2;
|
||||||
|
retval += 2;
|
||||||
|
} else {
|
||||||
|
return retval + convert_string_internal(from, to, p, srclen, q, destlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
return convert_string_internal(from, to, src, srclen, dest, destlen);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert between character sets, allocating a new buffer for the result.
|
* Convert between character sets, allocating a new buffer for the result.
|
||||||
*
|
*
|
||||||
@ -925,8 +1006,10 @@ size_t push_string_fn(const char *function, unsigned int line, const void *base_
|
|||||||
|
|
||||||
size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
|
size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
|
||||||
{
|
{
|
||||||
|
#ifdef DEVELOPER
|
||||||
if (dest_len != (size_t)-1)
|
if (dest_len != (size_t)-1)
|
||||||
clobber_region(function, line, dest, dest_len);
|
clobber_region(function, line, dest, dest_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(flags & STR_ASCII) && \
|
if (!(flags & STR_ASCII) && \
|
||||||
((flags & STR_UNICODE || \
|
((flags & STR_UNICODE || \
|
||||||
|
@ -503,7 +503,9 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEVELOPER
|
||||||
clobber_region(fn,line,dest, maxlength+1);
|
clobber_region(fn,line,dest, maxlength+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!src) {
|
if (!src) {
|
||||||
*dest = 0;
|
*dest = 0;
|
||||||
@ -542,7 +544,9 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size
|
|||||||
src_len = strnlen(src, maxlength + 1);
|
src_len = strnlen(src, maxlength + 1);
|
||||||
dest_len = strnlen(dest, maxlength + 1);
|
dest_len = strnlen(dest, maxlength + 1);
|
||||||
|
|
||||||
|
#ifdef DEVELOPER
|
||||||
clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
|
clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (src_len + dest_len > maxlength) {
|
if (src_len + dest_len > maxlength) {
|
||||||
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
|
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
|
||||||
@ -569,7 +573,9 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
|
|||||||
{
|
{
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
|
||||||
|
#ifdef DEVELOPER
|
||||||
clobber_region(fn, line, dest, maxlength);
|
clobber_region(fn, line, dest, maxlength);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
|
DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
|
||||||
@ -609,7 +615,9 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
|
|||||||
{
|
{
|
||||||
char *d = dest;
|
char *d = dest;
|
||||||
|
|
||||||
|
#ifdef DEVELOPER
|
||||||
clobber_region(fn, line, dest, n+1);
|
clobber_region(fn, line, dest, n+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -639,8 +647,9 @@ static char *strncpyn(char *dest, const char *src, size_t n, char c)
|
|||||||
char *p;
|
char *p;
|
||||||
size_t str_len;
|
size_t str_len;
|
||||||
|
|
||||||
|
#ifdef DEVELOPER
|
||||||
clobber_region(dest, n+1);
|
clobber_region(dest, n+1);
|
||||||
|
#endif
|
||||||
p = strchr_m(src, c);
|
p = strchr_m(src, c);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
|
DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
|
||||||
|
@ -299,9 +299,12 @@ struct cli_state *cli_initialise(struct cli_state *cli)
|
|||||||
memset(cli->outbuf, 0, cli->bufsize);
|
memset(cli->outbuf, 0, cli->bufsize);
|
||||||
memset(cli->inbuf, 0, cli->bufsize);
|
memset(cli->inbuf, 0, cli->bufsize);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(DEVELOPER)
|
||||||
/* just because we over-allocate, doesn't mean it's right to use it */
|
/* just because we over-allocate, doesn't mean it's right to use it */
|
||||||
clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);
|
clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);
|
||||||
clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);
|
clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* initialise signing */
|
/* initialise signing */
|
||||||
cli_null_set_signing(cli);
|
cli_null_set_signing(cli);
|
||||||
|
@ -1265,8 +1265,10 @@ void smbd_process(void)
|
|||||||
if ((InBuffer == NULL) || (OutBuffer == NULL))
|
if ((InBuffer == NULL) || (OutBuffer == NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(DEVELOPER)
|
||||||
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
|
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
|
||||||
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
|
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
|
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
|
||||||
|
|
||||||
@ -1295,7 +1297,9 @@ void smbd_process(void)
|
|||||||
num_smbs = 0; /* Reset smb counter. */
|
num_smbs = 0; /* Reset smb counter. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEVELOPER)
|
||||||
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
|
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
|
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
|
||||||
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
|
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
|
||||||
|
Reference in New Issue
Block a user