summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorMichael Widenius <monty@mysql.com>2008-12-03 06:07:50 +0200
committerMichael Widenius <monty@mysql.com>2008-12-03 06:07:50 +0200
commitfb68158856f8d74372c8fa0c14553cd18dc9811b (patch)
tree75dce448d62eb219bf1c6fd013ba1a47a3d5ef89 /mysys
parentea7cb6c2735a8ecfc380b67c437b2ead6608d765 (diff)
parent2b51150231841c37753579029cc5b2005514fd2b (diff)
downloadmariadb-git-fb68158856f8d74372c8fa0c14553cd18dc9811b.tar.gz
Merge with base MySQL-5.1-maria
Diffstat (limited to 'mysys')
-rw-r--r--mysys/hash.c149
-rw-r--r--mysys/lf_hash.c7
-rw-r--r--mysys/my_getopt.c3
-rw-r--r--mysys/my_symlink.c17
-rw-r--r--mysys/stacktrace.c67
-rw-r--r--mysys/thr_mutex.c49
-rw-r--r--mysys/waiting_threads.c12
7 files changed, 196 insertions, 108 deletions
diff --git a/mysys/hash.c b/mysys/hash.c
index 0d3f79bc40f..ba606e835a8 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -33,7 +33,7 @@ typedef struct st_hash_info {
uchar *data; /* data for current entry */
} HASH_LINK;
-static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
+static uint my_hash_mask(uint hashnr, uint buffmax, uint maxlength);
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
size_t length);
@@ -46,19 +46,19 @@ static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
}
my_bool
-_hash_init(HASH *hash,uint growth_size, CHARSET_INFO *charset,
- ulong size, size_t key_offset, size_t key_length,
- hash_get_key get_key,
- void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
+_my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
+ ulong size, size_t key_offset, size_t key_length,
+ my_hash_get_key get_key,
+ void (*free_element)(void*), uint flags CALLER_INFO_PROTO)
{
- DBUG_ENTER("hash_init");
+ DBUG_ENTER("my_hash_init");
DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size));
hash->records=0;
if (my_init_dynamic_array_ci(&hash->array, sizeof(HASH_LINK), size,
growth_size))
{
- hash->free=0; /* Allow call to hash_free */
+ hash->free=0; /* Allow call to my_hash_free */
DBUG_RETURN(1);
}
hash->key_offset=key_offset;
@@ -76,14 +76,14 @@ _hash_init(HASH *hash,uint growth_size, CHARSET_INFO *charset,
Call hash->free on all elements in hash.
SYNOPSIS
- hash_free_elements()
+ my_hash_free_elements()
hash hash table
NOTES:
Sets records to 0
*/
-static inline void hash_free_elements(HASH *hash)
+static inline void my_hash_free_elements(HASH *hash)
{
if (hash->free)
{
@@ -100,18 +100,18 @@ static inline void hash_free_elements(HASH *hash)
Free memory used by hash.
SYNOPSIS
- hash_free()
+ my_hash_free()
hash the hash to delete elements of
- NOTES: Hash can't be reused without calling hash_init again.
+ NOTES: Hash can't be reused without calling my_hash_init again.
*/
-void hash_free(HASH *hash)
+void my_hash_free(HASH *hash)
{
- DBUG_ENTER("hash_free");
+ DBUG_ENTER("my_hash_free");
DBUG_PRINT("enter",("hash: 0x%lx", (long) hash));
- hash_free_elements(hash);
+ my_hash_free_elements(hash);
hash->free= 0;
delete_dynamic(&hash->array);
DBUG_VOID_RETURN;
@@ -131,7 +131,7 @@ void my_hash_reset(HASH *hash)
DBUG_ENTER("my_hash_reset");
DBUG_PRINT("enter",("hash: 0x%lxd", (long) hash));
- hash_free_elements(hash);
+ my_hash_free_elements(hash);
reset_dynamic(&hash->array);
/* Set row pointers so that the hash can be reused at once */
hash->blength= 1;
@@ -146,8 +146,8 @@ void my_hash_reset(HASH *hash)
*/
static inline char*
-hash_key(const HASH *hash, const uchar *record, size_t *length,
- my_bool first)
+my_hash_key(const HASH *hash, const uchar *record, size_t *length,
+ my_bool first)
{
if (hash->get_key)
return (char*) (*hash->get_key)(record,length,first);
@@ -157,18 +157,18 @@ hash_key(const HASH *hash, const uchar *record, size_t *length,
/* Calculate pos according to keys */
-static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
+static uint my_hash_mask(uint hashnr, uint buffmax, uint maxlength)
{
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
return (hashnr & ((buffmax >> 1) -1));
}
-static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos,
- uint buffmax, uint maxlength)
+static uint my_hash_rec_mask(const HASH *hash, HASH_LINK *pos,
+ uint buffmax, uint maxlength)
{
size_t length;
- uchar *key= (uchar*) hash_key(hash,pos->data,&length,0);
- return hash_mask(calc_hash(hash,key,length),buffmax,maxlength);
+ uchar *key= (uchar*) my_hash_key(hash, pos->data, &length, 0);
+ return my_hash_mask(calc_hash(hash, key, length), buffmax, maxlength);
}
@@ -181,15 +181,15 @@ inline
unsigned int rec_hashnr(HASH *hash,const uchar *record)
{
size_t length;
- uchar *key= (uchar*) hash_key(hash,record,&length,0);
+ uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
return calc_hash(hash,key,length);
}
-uchar* hash_search(const HASH *hash, const uchar *key, size_t length)
+uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
{
HASH_SEARCH_STATE state;
- return hash_first(hash, key, length, &state);
+ return my_hash_first(hash, key, length, &state);
}
/*
@@ -199,18 +199,18 @@ uchar* hash_search(const HASH *hash, const uchar *key, size_t length)
Assigns the number of the found record to HASH_SEARCH_STATE state
*/
-uchar* hash_first(const HASH *hash, const uchar *key, size_t length,
- HASH_SEARCH_STATE *current_record)
+uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
+ HASH_SEARCH_STATE *current_record)
{
HASH_LINK *pos;
uint flag,idx;
- DBUG_ENTER("hash_first");
+ DBUG_ENTER("my_hash_first");
flag=1;
if (hash->records)
{
- idx=hash_mask(calc_hash(hash,key,length ? length : hash->key_length),
- hash->blength,hash->records);
+ idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length),
+ hash->blength, hash->records);
do
{
pos= dynamic_element(&hash->array,idx,HASH_LINK*);
@@ -223,7 +223,7 @@ uchar* hash_first(const HASH *hash, const uchar *key, size_t length,
if (flag)
{
flag=0; /* Reset flag */
- if (hash_rec_mask(hash,pos,hash->blength,hash->records) != idx)
+ if (my_hash_rec_mask(hash, pos, hash->blength, hash->records) != idx)
break; /* Wrong link */
}
}
@@ -234,10 +234,10 @@ uchar* hash_first(const HASH *hash, const uchar *key, size_t length,
}
/* Get next record with identical key */
- /* Can only be called if previous calls was hash_search */
+ /* Can only be called if previous calls was my_hash_search */
-uchar* hash_next(const HASH *hash, const uchar *key, size_t length,
- HASH_SEARCH_STATE *current_record)
+uchar* my_hash_next(const HASH *hash, const uchar *key, size_t length,
+ HASH_SEARCH_STATE *current_record)
{
HASH_LINK *pos;
uint idx;
@@ -297,7 +297,7 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
size_t length)
{
size_t rec_keylength;
- uchar *rec_key= (uchar*) hash_key(hash,pos->data,&rec_keylength,1);
+ uchar *rec_key= (uchar*) my_hash_key(hash, pos->data, &rec_keylength, 1);
return ((length && length != rec_keylength) ||
my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength,
(uchar*) key, rec_keylength));
@@ -312,7 +312,7 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
@retval 1 Duplicate key or out of memory
*/
-my_bool my_hash_insert(HASH *info,const uchar *record)
+my_bool my_hash_insert(HASH *info, const uchar *record)
{
int flag;
size_t idx;
@@ -327,8 +327,8 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
if (info->flags & HASH_UNIQUE)
{
- uchar *key= (uchar*) hash_key(info, record, &idx, 1);
- if (hash_search(info, key, idx))
+ uchar *key= (uchar*) my_hash_key(info, record, &idx, 1);
+ if (my_hash_search(info, key, idx))
return(TRUE); /* Duplicate entry */
}
@@ -347,7 +347,7 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
pos=data+idx;
hash_nr=rec_hashnr(info,pos->data);
if (flag == 0) /* First loop; Check if ok */
- if (hash_mask(hash_nr,info->blength,info->records) != first_index)
+ if (my_hash_mask(hash_nr, info->blength, info->records) != first_index)
break;
if (!(hash_nr & halfbuff))
{ /* Key will not move */
@@ -419,7 +419,7 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
}
/* Check if we are at the empty position */
- idx=hash_mask(rec_hashnr(info,record),info->blength,info->records+1);
+ idx= my_hash_mask(rec_hashnr(info, record), info->blength, info->records + 1);
pos=data+idx;
if (pos == empty)
{
@@ -430,7 +430,7 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
{
/* Check if more records in same hash-nr family */
empty[0]=pos[0];
- gpos=data+hash_rec_mask(info,pos,info->blength,info->records+1);
+ gpos= data + my_hash_rec_mask(info, pos, info->blength, info->records + 1);
if (pos == gpos)
{
pos->data=(uchar*) record;
@@ -465,18 +465,18 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
@retval 1 Record not found
*/
-my_bool hash_delete(HASH *hash,uchar *record)
+my_bool my_hash_delete(HASH *hash, uchar *record)
{
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
- DBUG_ENTER("hash_delete");
+ DBUG_ENTER("my_hash_delete");
if (!hash->records)
DBUG_RETURN(1);
blength=hash->blength;
data=dynamic_element(&hash->array,0,HASH_LINK*);
/* Search after record with key */
- pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
+ pos= data + my_hash_mask(rec_hashnr(hash, record), blength, hash->records);
gpos = 0;
while (pos->data != record)
@@ -507,7 +507,7 @@ my_bool hash_delete(HASH *hash,uchar *record)
/* Move the last key (lastpos) */
lastpos_hashnr=rec_hashnr(hash,lastpos->data);
/* pos is where lastpos should be */
- pos=data+hash_mask(lastpos_hashnr,hash->blength,hash->records);
+ pos= data + my_hash_mask(lastpos_hashnr, hash->blength, hash->records);
if (pos == empty) /* Move to empty position. */
{
empty[0]=lastpos[0];
@@ -515,7 +515,7 @@ my_bool hash_delete(HASH *hash,uchar *record)
}
pos_hashnr=rec_hashnr(hash,pos->data);
/* pos3 is where the pos should be */
- pos3= data+hash_mask(pos_hashnr,hash->blength,hash->records);
+ pos3= data + my_hash_mask(pos_hashnr, hash->blength, hash->records);
if (pos != pos3)
{ /* pos is on wrong posit */
empty[0]=pos[0]; /* Save it here */
@@ -523,8 +523,8 @@ my_bool hash_delete(HASH *hash,uchar *record)
movelink(data,(uint) (pos-data),(uint) (pos3-data),empty_index);
goto exit;
}
- pos2= hash_mask(lastpos_hashnr,blength,hash->records+1);
- if (pos2 == hash_mask(pos_hashnr,blength,hash->records+1))
+ pos2= my_hash_mask(lastpos_hashnr, blength, hash->records + 1);
+ if (pos2 == my_hash_mask(pos_hashnr, blength, hash->records + 1))
{ /* Identical key-positions */
if (pos2 != hash->records)
{
@@ -547,31 +547,32 @@ exit:
DBUG_RETURN(0);
}
- /*
- Update keys when record has changed.
- This is much more efficent than using a delete & insert.
- */
-my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
- size_t old_key_length)
+/**
+ Update keys when record has changed.
+ This is much more efficent than using a delete & insert.
+*/
+
+my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
+ size_t old_key_length)
{
uint new_index,new_pos_index,blength,records,empty;
size_t idx;
HASH_LINK org_link,*data,*previous,*pos;
- DBUG_ENTER("hash_update");
+ DBUG_ENTER("my_hash_update");
if (HASH_UNIQUE & hash->flags)
{
HASH_SEARCH_STATE state;
- uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1);
- if ((found= hash_first(hash, new_key, idx, &state)))
+ uchar *found, *new_key= (uchar*) my_hash_key(hash, record, &idx, 1);
+ if ((found= my_hash_first(hash, new_key, idx, &state)))
{
do
{
if (found != record)
DBUG_RETURN(1); /* Duplicate entry */
}
- while ((found= hash_next(hash, new_key, idx, &state)));
+ while ((found= my_hash_next(hash, new_key, idx, &state)));
}
}
@@ -580,11 +581,11 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
/* Search after record with key */
- idx=hash_mask(calc_hash(hash, old_key,(old_key_length ?
- old_key_length :
- hash->key_length)),
- blength,records);
- new_index=hash_mask(rec_hashnr(hash,record),blength,records);
+ idx= my_hash_mask(calc_hash(hash, old_key, (old_key_length ?
+ old_key_length :
+ hash->key_length)),
+ blength, records);
+ new_index= my_hash_mask(rec_hashnr(hash, record), blength, records);
if (idx == new_index)
DBUG_RETURN(0); /* Nothing to do (No record check) */
previous=0;
@@ -634,7 +635,7 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
DBUG_RETURN(0);
}
pos=data+new_index;
- new_pos_index=hash_rec_mask(hash,pos,blength,records);
+ new_pos_index= my_hash_rec_mask(hash, pos, blength, records);
if (new_index != new_pos_index)
{ /* Other record in wrong position */
data[empty] = *pos;
@@ -652,7 +653,7 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
}
-uchar *hash_element(HASH *hash,ulong idx)
+uchar *my_hash_element(HASH *hash, ulong idx)
{
if (idx < hash->records)
return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
@@ -665,7 +666,8 @@ uchar *hash_element(HASH *hash,ulong idx)
isn't changed
*/
-void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, uchar *new_row)
+void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record,
+ uchar *new_row)
{
if (*current_record != NO_RECORD) /* Safety */
dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;
@@ -686,7 +688,7 @@ void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, uchar *new_row)
@retval 1 iteration aborted becasue action returned 1
*/
-my_bool hash_iterate(HASH *hash, hash_walk_action action, void *argument)
+my_bool my_hash_iterate(HASH *hash, my_hash_walk_action action, void *argument)
{
uint records, i;
HASH_LINK *data;
@@ -705,7 +707,7 @@ my_bool hash_iterate(HASH *hash, hash_walk_action action, void *argument)
#ifndef DBUG_OFF
-my_bool hash_check(HASH *hash)
+my_bool my_hash_check(HASH *hash)
{
int error;
uint i,rec_link,found,max_links,seek,links,idx;
@@ -718,7 +720,7 @@ my_bool hash_check(HASH *hash)
for (i=found=max_links=seek=0 ; i < records ; i++)
{
- if (hash_rec_mask(hash,data+i,blength,records) == i)
+ if (my_hash_rec_mask(hash, data + i, blength, records) == i)
{
found++; seek++; links=1;
for (idx=data[i].next ;
@@ -734,11 +736,12 @@ my_bool hash_check(HASH *hash)
}
hash_info=data+idx;
seek+= ++links;
- if ((rec_link=hash_rec_mask(hash,hash_info,blength,records)) != i)
+ if ((rec_link= my_hash_rec_mask(hash, hash_info,
+ blength, records)) != i)
{
- DBUG_PRINT("error",
- ("Record in wrong link at %d: Start %d Record: 0x%lx Record-link %d",
- idx, i, (long) hash_info->data, rec_link));
+ DBUG_PRINT("error", ("Record in wrong link at %d: Start %d "
+ "Record: 0x%lx Record-link %d",
+ idx, i, (long) hash_info->data, rec_link));
error=1;
}
else
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index 008abef0c8b..96ae3f338ab 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -281,8 +281,9 @@ static inline const uchar* hash_key(const LF_HASH *hash,
}
/*
- compute the hash key value from the raw key.
- note, that the hash value is limited to 2^31, because we need one
+ Compute the hash key value from the raw key.
+
+ @note, that the hash value is limited to 2^31, because we need one
bit to distinguish between normal and dummy nodes.
*/
static inline uint calc_hash(LF_HASH *hash, const uchar *key, uint keylen)
@@ -300,7 +301,7 @@ static int initialize_bucket(LF_HASH *, LF_SLIST * volatile*, uint, LF_PINS *);
/*
Initializes lf_hash, the arguments are compatible with hash_init
- @@note element_size sets both the size of allocated memory block for
+ @note element_size sets both the size of allocated memory block for
lf_alloc and a size of memcpy'ed block size in lf_hash_insert. Typically
they are the same, indeed. But LF_HASH::element_size can be decreased
after lf_hash_init, and then lf_alloc will allocate larger block that
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index ddb0a4d3ed5..059896f5081 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -39,8 +39,7 @@ static ulonglong getopt_ull(char *arg, const struct my_option *optp,
static double getopt_double(char *arg, const struct my_option *optp, int *err);
static void init_variables(const struct my_option *options,
init_func_p init_one_value);
-static void init_one_value(const struct my_option *option, uchar* *variable,
- longlong value);
+static void init_one_value(const struct my_option *opt, uchar* *, longlong);
static void fini_one_value(const struct my_option *option, uchar* *variable,
longlong value);
static int setval(const struct my_option *opts, uchar **value, char *argument,
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index f8c6ebf02c3..258e227bb7b 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -90,16 +90,6 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags)
#endif /* HAVE_READLINK */
}
-/*
- Resolve all symbolic links in path
- 'to' may be equal to 'filename'
-
- Because purify gives a lot of UMR errors when using realpath(),
- this code is disabled when using purify.
-
- If MY_RESOLVE_LINK is given, only do realpath if the file is a link.
-*/
-
#if defined(SCO)
#define BUFF_LEN 4097
#elif defined(MAXPATHLEN)
@@ -124,10 +114,15 @@ int my_is_symlink(const char *filename __attribute__((unused)))
}
+/*
+ Resolve all symbolic links in path
+ 'to' may be equal to 'filename'
+*/
+
int my_realpath(char *to, const char *filename,
myf MyFlags __attribute__((unused)))
{
-#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
+#if defined(HAVE_REALPATH) && !defined(HAVE_BROKEN_REALPATH)
int result=0;
char buff[BUFF_LEN];
char *ptr;
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 5b941bbd7d6..66a361b5421 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -317,6 +317,7 @@ void my_write_core(int sig)
#else /* __WIN__*/
#include <dbghelp.h>
+#include <tlhelp32.h>
/*
Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
@@ -409,6 +410,68 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
exception_ptrs = ep;
}
+
+/*
+ Get symbol path - semicolon-separated list of directories to search for debug
+ symbols. We expect PDB in the same directory as corresponding exe or dll,
+ so the path is build from directories of the loaded modules. If environment
+ variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path
+*/
+static void get_symbol_path(char *path, size_t size)
+{
+ HANDLE hSnap;
+ char *envvar;
+
+ path[0]= '\0';
+ /*
+ Enumerate all modules, and add their directories to the path.
+ Avoid duplicate entries.
+ */
+ hSnap= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
+ if (hSnap != INVALID_HANDLE_VALUE)
+ {
+ BOOL ret;
+ MODULEENTRY32 mod;
+ mod.dwSize= sizeof(MODULEENTRY32);
+ for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod))
+ {
+ char *module_dir= mod.szExePath;
+ char *p= strrchr(module_dir,'\\');
+ if (!p)
+ {
+ /*
+ Path separator was not found. Not known to happen, if ever happens,
+ will indicate current directory.
+ */
+ module_dir[0]= '.';
+ p= module_dir + 1;
+ }
+ *p++= ';';
+ *p= '\0';
+
+ if (!strstr(path, module_dir))
+ {
+ size_t dir_len = strlen(module_dir);
+ if (size > dir_len)
+ {
+ strncat(path, module_dir, size-1);
+ size -= dir_len;
+ }
+ }
+ }
+ CloseHandle(hSnap);
+ }
+
+ /* Add _NT_SYMBOL_PATH, if present. */
+ envvar= getenv("_NT_SYMBOL_PATH");
+ if(envvar && size)
+ {
+ strncat(path, envvar, size-1);
+ }
+}
+
+#define MAX_SYMBOL_PATH 32768
+
/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
#ifndef SYMOPT_NO_PROMPTS
#define SYMOPT_NO_PROMPTS 0
@@ -425,6 +488,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
int i;
CONTEXT context;
STACKFRAME64 frame={0};
+ static char symbol_path[MAX_SYMBOL_PATH];
if(!exception_ptrs || !init_dbghelp_functions())
return;
@@ -433,7 +497,8 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
context = *(exception_ptrs->ContextRecord);
/*Initialize symbols.*/
pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
- pSymInitialize(hProcess,NULL,TRUE);
+ get_symbol_path(symbol_path, sizeof(symbol_path));
+ pSymInitialize(hProcess, symbol_path, TRUE);
/*Prepare stackframe for the first StackWalk64 call*/
frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index ddbe613cdae..4f19f5d79c4 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -308,9 +308,9 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
are now locking (C) in B->C, then we would add C into
B->locked_mutex and A->locked_mutex
*/
- hash_iterate(mutex_root->used_mutex,
- (hash_walk_action) add_used_to_locked_mutex,
- deadlock);
+ my_hash_iterate(mutex_root->used_mutex,
+ (my_hash_walk_action) add_used_to_locked_mutex,
+ deadlock);
/*
Copy all current mutex and all mutex locked after current one
@@ -584,10 +584,12 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp)
if (!(mp->create_flags & MYF_NO_DEADLOCK_DETECTION))
{
pthread_mutex_lock(&THR_LOCK_mutex);
- hash_iterate(mp->used_mutex, (hash_walk_action) remove_from_locked_mutex,
- mp);
- hash_iterate(mp->locked_mutex, (hash_walk_action) remove_from_used_mutex,
- mp);
+ my_hash_iterate(mp->used_mutex,
+ (my_hash_walk_action) remove_from_locked_mutex,
+ mp);
+ my_hash_iterate(mp->locked_mutex,
+ (my_hash_walk_action) remove_from_used_mutex,
+ mp);
pthread_mutex_unlock(&THR_LOCK_mutex);
hash_free(mp->used_mutex);
@@ -644,9 +646,9 @@ static my_bool add_used_to_locked_mutex(safe_mutex_t *used_mutex,
/* Add mutex to all parent of the current mutex */
if (!locked_mutex->warning_only)
{
- (void) hash_iterate(locked_mutex->mutex->locked_mutex,
- (hash_walk_action) add_to_locked_mutex,
- used_mutex);
+ (void) my_hash_iterate(locked_mutex->mutex->locked_mutex,
+ (my_hash_walk_action) add_to_locked_mutex,
+ used_mutex);
/* mark that locked_mutex is locked after used_mutex */
(void) add_to_locked_mutex(locked_mutex, used_mutex);
}
@@ -806,9 +808,33 @@ int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp,
mp->spins= MY_PTHREAD_FASTMUTEX_SPINS;
else
mp->spins= 0;
+ mp->rng_state= 1;
return pthread_mutex_init(&mp->mutex, attr);
}
+/**
+ Park-Miller random number generator. A simple linear congruential
+ generator that operates in multiplicative group of integers modulo n.
+
+ x_{k+1} = (x_k g) mod n
+
+ Popular pair of parameters: n = 2^32 − 5 = 4294967291 and g = 279470273.
+ The period of the generator is about 2^31.
+ Largest value that can be returned: 2147483646 (RAND_MAX)
+
+ Reference:
+
+ S. K. Park and K. W. Miller
+ "Random number generators: good ones are hard to find"
+ Commun. ACM, October 1988, Volume 31, No 10, pages 1192-1201.
+*/
+
+static double park_rng(my_pthread_fastmutex_t *mp)
+{
+ mp->rng_state= ((my_ulonglong)mp->rng_state * 279470273U) % 4294967291U;
+ return (mp->rng_state / 2147483647.0);
+}
+
int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp)
{
int res;
@@ -826,8 +852,7 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp)
return res;
mutex_delay(maxdelay);
- maxdelay += ((double) random() / (double) RAND_MAX) *
- MY_PTHREAD_FASTMUTEX_DELAY + 1;
+ maxdelay += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1;
}
return pthread_mutex_lock(&mp->mutex);
}
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c
index ef19018831b..14b1d639d00 100644
--- a/mysys/waiting_threads.c
+++ b/mysys/waiting_threads.c
@@ -280,7 +280,7 @@ void wt_init()
DBUG_ENTER("wt_init");
lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0,
- sizeof(struct st_wt_resource_id), 0, 0);
+ sizeof_WT_RESOURCE_ID, 0, 0);
reshash.alloc.constructor= wt_resource_init;
reshash.alloc.destructor= wt_resource_destroy;
/*
@@ -396,9 +396,9 @@ void wt_thd_destroy(WT_THD *thd)
*/
int wt_resource_id_memcmp(void *a, void *b)
{
- /* assert that the structure is not padded with random bytes */
- compile_time_assert(sizeof(WT_RESOURCE_ID)==sizeof(ulonglong)+sizeof(void*));
- return memcmp(a, b, sizeof(WT_RESOURCE_ID));
+ /* we use the fact that there's no padding in the middle of WT_RESOURCE_ID */
+ compile_time_assert(offsetof(WT_RESOURCE_ID, type) == sizeof(ulonglong));
+ return memcmp(a, b, sizeof_WT_RESOURCE_ID);
}
/**
@@ -657,7 +657,7 @@ static int unlock_lock_and_free_resource(WT_THD *thd, WT_RESOURCE *rc)
/* XXX if (rc->id.type->make_key) key= rc->id.type->make_key(&rc->id, &keylen); else */
{
key= &rc->id;
- keylen= sizeof(rc->id);
+ keylen= sizeof_WT_RESOURCE_ID;
}
/*
@@ -751,7 +751,7 @@ int wt_thd_will_wait_for(WT_THD *thd, WT_THD *blocker, WT_RESOURCE_ID *resid)
/* XXX if (restype->make_key) key= restype->make_key(resid, &keylen); else */
{
key= resid;
- keylen= sizeof(*resid);
+ keylen= sizeof_WT_RESOURCE_ID;
}
DBUG_PRINT("wt", ("first blocker"));