summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/charset.c4
-rw-r--r--mysys/default.c6
-rw-r--r--mysys/mf_keycache.c84
-rw-r--r--mysys/mf_soundex.c4
-rw-r--r--mysys/my_getopt.c30
-rw-r--r--mysys/my_getsystime.c27
-rw-r--r--mysys/my_thr_init.c3
7 files changed, 122 insertions, 36 deletions
diff --git a/mysys/charset.c b/mysys/charset.c
index 80f62b06a3e..e58c851cf7c 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -97,7 +97,7 @@ static void init_state_maps(CHARSET_INFO *cs)
state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL;
state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT;
- state_map[(uchar)';']=(uchar) MY_LEX_COLON;
+ state_map[(uchar)';']=(uchar) MY_LEX_SEMICOLON;
state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR;
state_map[0]=(uchar) MY_LEX_EOL;
state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE;
@@ -373,7 +373,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
uint len;
MY_STAT stat_info;
- if (!my_stat(filename, &stat_info, MYF(MY_WME)) ||
+ if (!my_stat(filename, &stat_info, MYF(myflags)) ||
((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
!(buf= (char *)my_malloc(len,myflags)))
return TRUE;
diff --git a/mysys/default.c b/mysys/default.c
index d09b0dd97af..af67520322f 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -166,6 +166,12 @@ int load_defaults(const char *conf_file, const char **groups,
if ((error= search_default_file(&args, &alloc, "",
forced_default_file, "", &group)) < 0)
goto err;
+ if (error > 0)
+ {
+ fprintf(stderr, "Could not open required defaults file: %s\n",
+ forced_default_file);
+ goto err;
+ }
}
else if (dirname_length(conf_file))
{
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 689391537f8..168483f276b 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -20,6 +20,23 @@
One cache can handle many files.
It must contain buffers of the same blocksize.
init_key_cache() should be used to init cache handler.
+
+ The free list (free_block_list) is a stack like structure.
+ When a block is freed by free_block(), it is pushed onto the stack.
+ When a new block is required it is first tried to pop one from the stack.
+ If the stack is empty, it is tried to get a never-used block from the pool.
+ If this is empty too, then a block is taken from the LRU ring, flushing it
+ to disk, if neccessary. This is handled in find_key_block().
+ With the new free list, the blocks can have three temperatures:
+ hot, warm and cold (which is free). This is remembered in the block header
+ by the enum BLOCK_TEMPERATURE temperature variable. Remembering the
+ temperature is neccessary to correctly count the number of warm blocks,
+ which is required to decide when blocks are allowed to become hot. Whenever
+ a block is inserted to another (sub-)chain, we take the old and new
+ temperature into account to decide if we got one more or less warm block.
+ blocks_unused is the sum of never used blocks in the pool and of currently
+ free blocks. blocks_used is the number of blocks fetched from the pool and
+ as such gives the maximum number of in-use blocks at any time.
*/
#include "mysys_priv.h"
@@ -116,6 +133,9 @@ struct st_hash_link
#define PAGE_TO_BE_READ 1
#define PAGE_WAIT_TO_BE_READ 2
+/* block temperature determines in which (sub-)chain the block currently is */
+enum BLOCK_TEMPERATURE { BLOCK_COLD /*free*/ , BLOCK_WARM , BLOCK_HOT };
+
/* key cache block */
struct st_block_link
{
@@ -130,6 +150,7 @@ struct st_block_link
uint offset; /* beginning of modified data in the buffer */
uint length; /* end of data in the buffer */
uint status; /* state of the block */
+ enum BLOCK_TEMPERATURE temperature; /* block temperature: cold, warm, hot */
uint hits_left; /* number of hits left until promotion */
ulonglong last_hit_time; /* timestamp of the last hit */
KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
@@ -340,6 +361,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
}
blocks= blocks / 4*3;
}
+ keycache->blocks_unused= (ulong) blocks;
keycache->disk_blocks= (int) blocks;
keycache->hash_links= hash_links;
keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root +
@@ -357,12 +379,13 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache->free_hash_list= NULL;
keycache->blocks_used= keycache->blocks_changed= 0;
- keycache->global_blocks_used= keycache->global_blocks_changed= 0;
+ keycache->global_blocks_changed= 0;
keycache->blocks_available=0; /* For debugging */
/* The LRU chain is empty after initialization */
keycache->used_last= NULL;
keycache->used_ins= NULL;
+ keycache->free_block_list= NULL;
keycache->keycache_time= 0;
keycache->warm_blocks= 0;
keycache->min_warm_blocks= (division_limit ?
@@ -596,7 +619,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
DBUG_PRINT("status",
("used: %d changed: %d w_requests: %ld \
writes: %ld r_requests: %ld reads: %ld",
- keycache->global_blocks_used, keycache->global_blocks_changed,
+ keycache->blocks_used, keycache->global_blocks_changed,
keycache->global_cache_w_requests, keycache->global_cache_write,
keycache->global_cache_r_requests, keycache->global_cache_read));
@@ -1014,7 +1037,9 @@ static inline void unreg_request(KEY_CACHE *keycache,
keycache->warm_blocks > keycache->min_warm_blocks;
if (hot)
{
- keycache->warm_blocks--;
+ if (block->temperature == BLOCK_WARM)
+ keycache->warm_blocks--;
+ block->temperature= BLOCK_HOT;
KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks=%u",
keycache->warm_blocks));
}
@@ -1026,7 +1051,11 @@ static inline void unreg_request(KEY_CACHE *keycache,
block= keycache->used_ins;
unlink_block(keycache, block);
link_block(keycache, block, 0, 0);
- keycache->warm_blocks++;
+ if (block->temperature != BLOCK_WARM)
+ {
+ keycache->warm_blocks++;
+ block->temperature= BLOCK_WARM;
+ }
KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks=%u",
keycache->warm_blocks));
}
@@ -1363,28 +1392,40 @@ restart:
if (! block)
{
/* No block is assigned for the page yet */
- if (keycache->blocks_used < (uint) keycache->disk_blocks)
+ if (keycache->blocks_unused)
{
- /* There are some never used blocks, take first of them */
- hash_link->block= block= &keycache->block_root[keycache->blocks_used];
- block->buffer= ADD_TO_PTR(keycache->block_mem,
- ((ulong) keycache->blocks_used*
- keycache->key_cache_block_size),
- byte*);
+ if (keycache->free_block_list)
+ {
+ /* There is a block in the free list. */
+ block= keycache->free_block_list;
+ keycache->free_block_list= block->next_used;
+ block->next_used= NULL;
+ }
+ else
+ {
+ /* There are some never used blocks, take first of them */
+ block= &keycache->block_root[keycache->blocks_used];
+ block->buffer= ADD_TO_PTR(keycache->block_mem,
+ ((ulong) keycache->blocks_used*
+ keycache->key_cache_block_size),
+ byte*);
+ keycache->blocks_used++;
+ }
+ keycache->blocks_unused--;
block->status= 0;
block->length= 0;
block->offset= keycache->key_cache_block_size;
block->requests= 1;
- keycache->blocks_used++;
- keycache->global_blocks_used++;
- keycache->warm_blocks++;
+ block->temperature= BLOCK_COLD;
block->hits_left= init_hits_left;
block->last_hit_time= 0;
link_to_file_list(keycache, block, file, 0);
block->hash_link= hash_link;
+ hash_link->block= block;
page_status= PAGE_TO_BE_READ;
KEYCACHE_DBUG_PRINT("find_key_block",
- ("got never used block %u", BLOCK_NUMBER(block)));
+ ("got free or never used block %u",
+ BLOCK_NUMBER(block)));
}
else
{
@@ -2021,7 +2062,7 @@ end:
/*
Free block: remove reference to it from hash table,
remove it from the chain file of dirty/clean blocks
- and add it at the beginning of the LRU chain
+ and add it to the free list.
*/
static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
@@ -2045,6 +2086,17 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
("block is freed"));
unreg_request(keycache, block, 0);
block->hash_link= NULL;
+
+ /* Remove the free block from the LRU ring. */
+ unlink_block(keycache, block);
+ if (block->temperature == BLOCK_WARM)
+ keycache->warm_blocks--;
+ block->temperature= BLOCK_COLD;
+ /* Insert the free block in the free list. */
+ block->next_used= keycache->free_block_list;
+ keycache->free_block_list= block;
+ /* Keep track of the number of currently unused blocks. */
+ keycache->blocks_unused++;
}
diff --git a/mysys/mf_soundex.c b/mysys/mf_soundex.c
index 75d9270c5af..27ab4892c57 100644
--- a/mysys/mf_soundex.c
+++ b/mysys/mf_soundex.c
@@ -52,7 +52,7 @@ void soundex(CHARSET_INFO * cs,register my_string out_pntr, my_string in_pntr,
if (remove_garbage)
{
- while (*in_pntr && my_isspace(cs,*in_pntr)) /* Skipp pre-space */
+ while (*in_pntr && !my_isalpha(cs,*in_pntr)) /* Skipp pre-space */
in_pntr++;
}
*out_pntr++ = map[(uchar)*in_pntr]; /* Copy first letter */
@@ -98,7 +98,7 @@ static char get_scode(CHARSET_INFO * cs,char **ptr, pbool remove_garbage)
ch=my_toupper(cs,**ptr);
if (ch < 'A' || ch > 'Z')
{
- if (my_isalpha(cs,ch)) /* If exetended alfa (country spec) */
+ if (my_isalpha(cs,ch)) /* If extended alfa (country spec) */
return '0'; /* threat as vokal */
return 0; /* Can't map */
}
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 8a1f6db6f8a..efd5789968c 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -342,8 +342,8 @@ int handle_options(int *argc, char ***argv,
{
if (!optend) /* No argument -> enable option */
*((my_bool*) value)= (my_bool) 1;
- else /* If argument differs from 0, enable option, else disable */
- *((my_bool*) value)= (my_bool) atoi(optend) != 0;
+ else
+ argument= optend;
}
}
else if (optp->arg_type == REQUIRED_ARG && !optend)
@@ -398,18 +398,25 @@ int handle_options(int *argc, char ***argv,
/* This is in effect a jump out of the outer loop */
optend= (char*) " ";
}
- else if (optp->arg_type == REQUIRED_ARG)
+ else
{
+ if (optp->arg_type == OPT_ARG)
+ {
+ if (optp->var_type == GET_BOOL)
+ *((my_bool*) optp->value)= (my_bool) 1;
+ get_one_option(optp->id, optp, argument);
+ continue;
+ }
/* Check if there are more arguments after this one */
- if (!*++pos)
+ if (!pos[1])
{
- if (my_getopt_print_errors)
- fprintf(stderr,
- "%s: option '-%c' requires an argument\n",
- my_progname, optp->id);
- return EXIT_ARGUMENT_REQUIRED;
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: option '-%c' requires an argument\n",
+ my_progname, optp->id);
+ return EXIT_ARGUMENT_REQUIRED;
}
- argument= *pos;
+ argument= *++pos;
(*argc)--;
/* the other loop will break, because *optend + 1 == 0 */
}
@@ -525,6 +532,9 @@ static int setval(const struct my_option *opts, gptr *value, char *argument,
return EXIT_NO_PTR_TO_VARIABLE;
switch ((opts->var_type & GET_TYPE_MASK)) {
+ case GET_BOOL: /* If argument differs from 0, enable option, else disable */
+ *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
+ break;
case GET_INT:
case GET_UINT: /* fall through */
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index bdaa232d560..91c977f0b5a 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -30,11 +30,28 @@ ulonglong my_getsystime()
clock_gettime(CLOCK_REALTIME, &tp);
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
#elif defined(__WIN__)
- /* TODO: use GetSystemTimeAsFileTime here or
- QueryPerformanceCounter/QueryPerformanceFrequency */
- struct _timeb tb;
- _ftime(&tb);
- return (ulonglong)tb.time*10000000+(ulonglong)tb.millitm*10000;
+#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
+ static __int64 offset=0, freq;
+ LARGE_INTEGER t_cnt;
+ if (!offset)
+ {
+ /* strictly speaking there should be a mutex to protect
+ initialization section. But my_getsystime() is called from
+ UUID() code, and UUID() calls are serialized with a mutex anyway
+ */
+ LARGE_INTEGER li;
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ li.LowPart=ft.dwLowDateTime;
+ li.HighPart=ft.dwHighDateTime;
+ offset=li.QuadPart-OFFSET_TO_EPOC;
+ QueryPerformanceFrequency(&li);
+ freq=li.QuadPart;
+ QueryPerformanceCounter(&t_cnt);
+ offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq;
+ }
+ QueryPerformanceCounter(&t_cnt);
+ return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset;
#elif defined(__NETWARE__)
NXTime_t tm;
NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 445cef0cd6f..0ce59bee346 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -203,7 +203,8 @@ void my_thread_end(void)
tmp->dbug=0;
}
#endif
-#if !defined(__bsdi__) || defined(HAVE_mit_thread) /* bsdi dumps core here */
+#if !defined(__bsdi__) && !defined(__OpenBSD__) || defined(HAVE_mit_thread)
+ /* bsdi and openbsd 3.5 dumps core here */
pthread_cond_destroy(&tmp->suspend);
#endif
pthread_mutex_destroy(&tmp->mutex);