Don't do signal() on windows (Causes instability problems)

Safer, a bit faster filesort.
Code changes to avoid calls to current_thd() (faster code).
Removed all compiler warnings from readline.


BitKeeper/etc/ignore:
  Add my_global.h back.
Docs/manual.texi:
  4.0.1 Changelog
include/my_sys.h:
  Added strmake_root
libmysql/libmysql.c:
  Don't do signal() on windows (Causes instability problems)
mysys/my_alloc.c:
  Added strmake_root
readline/bind.c:
  Remove warnings
readline/complete.c:
  Remove warnings
readline/display.c:
  Remove warnings
readline/funmap.c:
  Remove warnings
readline/histexpand.c:
  Remove warnings
readline/histfile.c:
  Remove warnings
readline/history.h:
  Remove warnings
readline/histsearch.c:
  Remove warnings
readline/isearch.c:
  Remove warnings
readline/kill.c:
  Remove warnings
readline/macro.c:
  Remove warnings
readline/readline.c:
  Remove warnings
readline/readline.h:
  Remove warnings
readline/rltty.c:
  Remove warnings
readline/search.c:
  Remove warnings
readline/shell.c:
  Remove warnings
readline/terminal.c:
  Remove warnings
readline/tilde.c:
  Remove warnings
readline/tilde.h:
  Remove warnings
readline/undo.c:
  Remove warnings
readline/util.c:
  Remove warnings
readline/vi_mode.c:
  Remove warnings
sql-bench/server-cfg.sh:
  Added use of truncate table
sql-bench/test-insert.sh:
  Added use of truncate table
  Changed some tests to use keys instead of 'range'
sql-bench/test-wisconsin.sh:
  Cleanup
sql/field.cc:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/field.h:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/filesort.cc:
  Safer memory allocation;  Don't allocate pointer to buffers directly, but use an IO_CACHE instead.
  This will allow us to use more memory for keys and will also work better if the number of rows that is to be sorted is much larger than expected.
sql/item.cc:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/item.h:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/item_func.h:
  Cleanup
sql/opt_range.cc:
  Use mem_root instead of sql_alloc() to get more speed
sql/sql_class.cc:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/sql_class.h:
  Added strmake()
sql/sql_handler.cc:
  Add 'thd' to send() (To avoid usage of 'current_thd')
sql/sql_lex.cc:
  Use mem_root instead of sql_alloc() to get more speed
sql/sql_select.cc:
  Add 'thd' to send() (To avoid usage of 'current_thd')
tests/fork2_test.pl:
  Fixed typos
tests/fork_big.pl:
  Fixed typos
tests/insert_and_repair.pl:
  Fixed typos
tests/rename_test.pl:
  Fixed typos
tests/test_delayed_insert.pl:
  Fixed typos
This commit is contained in:
unknown 2001-10-17 19:39:39 +03:00
parent 037c19e4ad
commit aeaf3fcf12
47 changed files with 353 additions and 325 deletions

View file

@ -180,7 +180,6 @@ gmon.out
heap/hp_test1
heap/hp_test2
include/my_config.h
include/my_global.h
include/mysql_version.h
include/widec.h
innobase/conftest.s1

View file

@ -129,7 +129,7 @@ distribution for that version.
@end menu
@node Introduction, Installing, Top, (dir)
@node Introduction, Installing, Top, Top
@chapter General Information About MySQL
@cindex overview
@ -47395,20 +47395,25 @@ features, so that others can follow our development.
Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@cindex changes, version 4.0
@menu
* News-4.0.1::
* News-4.0.0:: Changes in release 4.0.0
@end menu
@node News-4.0.0, , News-4.0.x, News-4.0.x
@appendixsubsec Changes in release 4.0.0
@cindex changes, version 4.0
@node News-4.0.1, News-4.0.0, News-4.0.x, News-4.0.x
@appendixsubsec Changes in release 4.0.1
@itemize @bullet
@item
Added boolean fulltext search code.
It should be considered early alpha.
Added boolean fulltext search code. It should be considered early alpha.
@end itemize
@node News-4.0.0, , News-4.0.1, News-4.0.x
@appendixsubsec Changes in release 4.0.0
@itemize @bullet
@item
Added documentation for @code{libmysqld}, the embedded MySQL server
library. Also added example programs (a @code{mysql} client and
@ -47420,6 +47425,9 @@ Removed @code{my_thread_init()} and @code{my_thread_end()}
from mysql_com.h, and added @code{mysql_thread_init()} and
@code{mysql_thread_end()} to mysql.h.
@item
Support for communication packets > 16M. In 4.0.1 we will extend MyISAM to
be able to handle these.
@item
Secure connections (with SSL).
@item
Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()}
@ -47436,7 +47444,7 @@ the database, which fixes a problem with InnoDB tables.
@item
Added support for @code{UNION}.
@item
@code(DELETE) and @code(UPDATE) can now operate on multiple tables.
@code{DELETE} can now operate on multiple tables.
@item
A new @code{HANDLER} interface to @code{MyISAM} tables.
@item

View file

@ -608,6 +608,7 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
void free_root(MEM_ROOT *root, myf MyFLAGS);
void set_prealloc_root(MEM_ROOT *root, char *ptr);
char *strdup_root(MEM_ROOT *root,const char *str);
char *strmake_root(MEM_ROOT *root,const char *str,uint len);
char *memdup_root(MEM_ROOT *root,const char *str,uint len);
void load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv);

View file

@ -1310,7 +1310,7 @@ mysql_init(MYSQL *mysql)
after we return if this is not the case.
*/
mysql->rpl_pivot = 1;
#if defined(SIGPIPE) && defined(THREAD)
#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler);
#endif
@ -1351,7 +1351,7 @@ static void mysql_once_init()
mysql_unix_port = env;
}
mysql_debug(NullS);
#if defined(SIGPIPE) && !defined(THREAD)
#if defined(SIGPIPE) && !defined(THREAD) && !defined(__WIN__)
(void) signal(SIGPIPE,SIG_IGN);
#endif
}

View file

@ -195,10 +195,17 @@ void set_prealloc_root(MEM_ROOT *root, char *ptr)
char *strdup_root(MEM_ROOT *root,const char *str)
{
uint len= (uint) strlen(str)+1;
return strmake_root(root, str, strlen(str));
}
char *strmake_root(MEM_ROOT *root,const char *str, uint len)
{
char *pos;
if ((pos=alloc_root(root,len)))
if ((pos=alloc_root(root,len+1)))
{
memcpy(pos,str,len);
pos[len]=0;
}
return pos;
}

View file

@ -108,7 +108,7 @@ Keymap rl_binding_keymap;
/* Forward declarations */
void rl_set_keymap_from_edit_mode ();
static int _rl_read_init_file ();
static int _rl_read_init_file (const char *filename, int include_level);
static int glean_key_from_name ();
static int substring_member_of_array ();
@ -570,10 +570,7 @@ rl_named_function (string)
type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
or ISMACR (macro). */
Function *
rl_function_of_keyseq (keyseq, map, type)
char *keyseq;
Keymap map;
int *type;
rl_function_of_keyseq (const char *keyseq, Keymap map, int *type)
{
register int i;
@ -629,7 +626,7 @@ rl_function_of_keyseq (keyseq, map, type)
static char *last_readline_init_file = (char *)NULL;
/* The file we're currently reading key bindings from. */
static char *current_readline_init_file;
static const char *current_readline_init_file;
static int current_readline_init_include_level;
static int current_readline_init_lineno;
@ -685,8 +682,8 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */
int
rl_re_read_init_file (count, ignore)
int count, ignore;
rl_re_read_init_file (int count __attribute__((unused)),
int ignore __attribute__((unused)))
{
int r;
r = rl_read_init_file ((char *)NULL);
@ -702,8 +699,7 @@ rl_re_read_init_file (count, ignore)
If the file existed and could be opened and read, 0 is returned,
otherwise errno is returned. */
int
rl_read_init_file (filename)
char *filename;
rl_read_init_file (const char *filename)
{
/* Default the filename. */
if (filename == 0)
@ -722,9 +718,7 @@ rl_read_init_file (filename)
}
static int
_rl_read_init_file (filename, include_level)
char *filename;
int include_level;
_rl_read_init_file (const char *filename, int include_level)
{
register int i;
char *buffer, *openname, *line, *end;
@ -797,7 +791,7 @@ _rl_init_file_error (msg)
/* Conditionals. */
/* Calling programs set this to have their argv[0]. */
char *rl_readline_name = "other";
const char *rl_readline_name = "other";
/* Stack of previous values of parsing_conditionalized_out. */
static unsigned char *if_stack = (unsigned char *)NULL;
@ -881,7 +875,7 @@ parser_if (args)
/* Invert the current parser state if there is anything on the stack. */
static int
parser_else (args)
char *args;
char *args __attribute__((unused));
{
register int i;
@ -906,7 +900,7 @@ parser_else (args)
_rl_parsing_conditionalized_out from the stack. */
static int
parser_endif (args)
char *args;
char *args __attribute__((unused));
{
if (if_stack_depth)
_rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
@ -919,7 +913,8 @@ static int
parser_include (args)
char *args;
{
char *old_init_file, *e;
const char *old_init_file;
char *e;
int old_line_number, old_include_level, r;
if (_rl_parsing_conditionalized_out)
@ -943,7 +938,7 @@ parser_include (args)
/* Associate textual names with actual functions. */
static struct {
char *name;
const char *name;
Function *function;
} parser_directives [] = {
{ "if", parser_if },
@ -1233,7 +1228,7 @@ rl_parse_and_bind (string)
false. */
static struct {
char *name;
const char *name;
int *value;
} boolean_varlist [] = {
#if defined (PAREN_MATCHING)
@ -1384,7 +1379,7 @@ rl_variable_bind (name, value)
For example, `Space' returns ' '. */
typedef struct {
char *name;
const char *name;
int value;
} assoc_list;
@ -1418,7 +1413,7 @@ glean_key_from_name (name)
/* Auxiliary functions to manage keymaps. */
static struct {
char *name;
const char *name;
Keymap map;
} keymap_names[] = {
{ "emacs", emacs_standard_keymap },
@ -1446,7 +1441,7 @@ rl_get_keymap_by_name (name)
return ((Keymap) NULL);
}
char *
const char *
rl_get_keymap_name (map)
Keymap map;
{
@ -1482,7 +1477,7 @@ rl_set_keymap_from_edit_mode ()
#endif /* VI_MODE */
}
char *
const char *
rl_get_keymap_name_from_edit_mode ()
{
if (rl_editing_mode == emacs_mode)
@ -1780,8 +1775,8 @@ rl_function_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
rl_dump_functions (count, key)
int count, key;
rl_dump_functions (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@ -1865,8 +1860,8 @@ rl_macro_dumper (print_readably)
}
int
rl_dump_macros (count, key)
int count, key;
rl_dump_macros (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@ -1880,7 +1875,7 @@ rl_variable_dumper (print_readably)
int print_readably;
{
int i;
char *kname;
const char *kname;
for (i = 0; boolean_varlist[i].name; i++)
{
@ -1955,8 +1950,8 @@ rl_variable_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
rl_dump_variables (count, key)
int count, key;
rl_dump_variables (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");

View file

@ -95,7 +95,7 @@ extern int rl_display_fixed;
VFunction *rl_completion_display_matches_hook = (VFunction *)NULL;
/* Forward declarations for functions defined and used in this file. */
char *filename_completion_function ();
char *filename_completion_function (const char *text, int state);
char **completion_matches ();
#if defined (VISIBLE_STATS)
@ -186,15 +186,15 @@ int rl_completion_query_items = 100;
/* The basic list of characters that signal a break between words for the
completer routine. The contents of this variable is what breaks words
in the shell, i.e. " \t\n\"\\'`@$><=" */
char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
/* List of basic quoting characters. */
char *rl_basic_quote_characters = "\"'";
const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
char *rl_completer_word_break_characters = (char *)NULL;
const char *rl_completer_word_break_characters = (char *)NULL;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -513,7 +513,7 @@ print_filename (to_print, full_pathname)
static char *
rl_quote_filename (s, rtype, qcp)
char *s;
int rtype;
int rtype __attribute__((unused));
char *qcp;
{
char *r;
@ -1356,9 +1356,7 @@ rl_complete_internal (what_to_do)
when there are no more matches.
*/
char **
completion_matches (text, entry_function)
char *text;
CPFunction *entry_function;
completion_matches (const char *text, CPFunction *entry_function)
{
/* Number of slots in match_list. */
int match_list_size;
@ -1403,9 +1401,7 @@ completion_matches (text, entry_function)
TEXT contains a partial username preceded by a random
character (usually `~'). */
char *
username_completion_function (text, state)
char *text;
int state;
username_completion_function (const char *text, int state)
{
#if defined (__GO32__) || defined (__WIN__) || defined (__OPENNT)
return (char *)NULL;
@ -1460,9 +1456,7 @@ username_completion_function (text, state)
because of all the pathnames that must be followed when looking up the
completion for a command. */
char *
filename_completion_function (text, state)
char *text;
int state;
filename_completion_function (const char *text, int state)
{
static DIR *directory = (DIR *)NULL;
static char *filename = (char *)NULL;
@ -1639,8 +1633,7 @@ filename_completion_function (text, state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
int
rl_menu_complete (count, ignore)
int count, ignore;
rl_menu_complete (int count, int ignore __attribute__((unused)))
{
Function *our_func;
int matching_filenames, found_quote;

View file

@ -79,9 +79,9 @@ extern int _rl_output_character_function ();
#endif
extern int _rl_backspace ();
extern char *term_clreol, *term_clrpag;
extern char *term_im, *term_ic, *term_ei, *term_DC;
extern char *term_up, *term_dc, *term_cr, *term_IC;
extern const char *term_clreol, *term_clrpag;
extern const char *term_im, *term_ic, *term_ei, *term_DC;
extern const char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, screenchars;
extern int terminal_can_insert, _rl_term_autowrap;
@ -141,7 +141,7 @@ int _rl_suppress_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
char *rl_display_prompt = (char *)NULL;
const char *rl_display_prompt = (char *)NULL;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
@ -315,7 +315,7 @@ rl_redisplay ()
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp;
char *prompt_this_line;
const char *prompt_this_line;
if (!readline_echoing_p)
return;
@ -1229,8 +1229,7 @@ rl_message (va_alist)
}
#else /* !USE_VARARGS */
int
rl_message (format, arg1, arg2)
char *format;
rl_message (char *format, void *arg1, void *arg2)
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
@ -1512,7 +1511,8 @@ cr ()
void
_rl_redisplay_after_sigwinch ()
{
char *t, *oldp, *oldl, *oldlprefix;
char *t, *oldl, *oldlprefix;
const char *oldp;
/* Clear the current line and put the cursor at column 0. Make sure
the right thing happens if we have wrapped to a new screen line. */

View file

@ -180,9 +180,7 @@ static FUNMAP default_funmap[] = {
};
int
rl_add_funmap_entry (name, function)
char *name;
Function *function;
rl_add_funmap_entry (const char *name, Function *function)
{
if (funmap_entry + 2 >= funmap_size)
{
@ -236,7 +234,7 @@ rl_funmap_names ()
result = (char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index] = funmap[result_index]->name;
result[result_index] = (char*) funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
@ -245,10 +243,10 @@ rl_funmap_names ()
}
/* Things that mean `Control'. */
char *possible_control_prefixes[] = {
const char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
};
char *possible_meta_prefixes[] = {
const char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};

View file

@ -87,7 +87,7 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */
char *history_no_expand_chars = " \t\n\r=";
const char *history_no_expand_chars = " \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */
@ -342,7 +342,8 @@ hist_error(s, start, current, errtype)
char *s;
int start, current, errtype;
{
char *temp, *emsg;
char *temp;
const char *emsg;
int ll, elen;
ll = current - start;

View file

@ -84,7 +84,8 @@ static char *
history_filename (filename)
char *filename;
{
char *return_val, *home;
char *return_val;
const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
@ -130,11 +131,10 @@ read_history_range (filename, from, to)
char *filename;
int from, to;
{
register int line_start, line_end;
char *input, *buffer;
int file, current_line;
struct stat finfo;
size_t file_size;
size_t line_start, line_end, file_size;
buffer = (char *)NULL;
input = history_filename (filename);

View file

@ -232,8 +232,8 @@ extern int max_input_history;
extern char history_expansion_char;
extern char history_subst_char;
extern char history_comment_char;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern const char *history_no_expand_chars;
extern const char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
/* If set, this function is called to decide whether or not a particular

View file

@ -52,7 +52,7 @@ extern int history_offset;
/* The list of alternate characters that can delimit a history search
string. */
char *history_search_delimiter_chars = (char *)NULL;
const char *history_search_delimiter_chars = (char *)NULL;
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else

View file

@ -97,7 +97,8 @@ rl_forward_search_history (sign, key)
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where;
int reverse_p;
int where __attribute__((unused));
{
char *message;
int msglen, searchlen;
@ -144,8 +145,7 @@ rl_display_search (search_string, reverse_p, where)
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction, invoking_key;
rl_search_history (int direction, int invoking_key __attribute__((unused)))
{
/* The string that the user types in to search for. */
char *search_string;

View file

@ -82,8 +82,7 @@ static int rl_kill_ring_length;
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (num)
int num;
rl_set_retained_kills (int num __attribute__((unused)))
{
return 0;
}
@ -285,8 +284,8 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (count, ignore)
int count, ignore;
rl_kill_full_line (int count __attribute__((unused)),
int ignore __attribute__((unused)))
{
rl_begin_undo_group ();
rl_point = 0;
@ -302,8 +301,7 @@ rl_kill_full_line (count, ignore)
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (count, key)
int count, key;
rl_unix_word_rubout (int count, int key __attribute__((unused)))
{
int orig_point;
@ -336,8 +334,8 @@ rl_unix_word_rubout (count, key)
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (count, key)
int count, key;
rl_unix_line_discard (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (rl_point == 0)
ding ();
@ -374,16 +372,16 @@ region_kill_internal (delete)
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (count, ignore)
int count, ignore;
rl_copy_region_to_kill (int count __attribute__((unused)),
int key __attribute__((unused)))
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (count, ignore)
int count, ignore;
rl_kill_region (int count __attribute__((unused)),
int key __attribute__((unused)))
{
int r;
@ -445,8 +443,8 @@ rl_copy_backward_word (count, key)
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (count, ignore)
int count, ignore;
rl_yank (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (rl_kill_ring == 0)
{
@ -464,8 +462,8 @@ rl_yank (count, ignore)
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (count, key)
int count, key;
rl_yank_pop (int count __attribute__((unused)),
int key __attribute__((unused)))
{
int l, n;

View file

@ -90,7 +90,7 @@ static int current_macro_index;
It is a linked list of string/index for each saved macro. */
struct saved_macro {
struct saved_macro *next;
char *string;
const char *string;
int sindex;
};
@ -100,11 +100,10 @@ static struct saved_macro *macro_list = (struct saved_macro *)NULL;
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
_rl_with_macro_input (string)
char *string;
_rl_with_macro_input (const char *string)
{
_rl_push_executing_macro ();
_rl_executing_macro = string;
_rl_executing_macro = (char*) string;
executing_macro_index = 0;
}
@ -155,7 +154,7 @@ _rl_pop_executing_macro ()
if (macro_list)
{
macro = macro_list;
_rl_executing_macro = macro_list->string;
_rl_executing_macro = (char*) macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
free (macro);
@ -206,8 +205,8 @@ _rl_kill_kbd_macro ()
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
rl_start_kbd_macro (ignore1, ignore2)
int ignore1, ignore2;
rl_start_kbd_macro (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (_rl_defining_kbd_macro)
{
@ -231,8 +230,7 @@ rl_start_kbd_macro (ignore1, ignore2)
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (count, ignore)
int count, ignore;
rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
{
if (_rl_defining_kbd_macro == 0)
{
@ -251,8 +249,7 @@ rl_end_kbd_macro (count, ignore)
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (count, ignore)
int count, ignore;
rl_call_last_kbd_macro (int count, int key __attribute__((unused)))
{
if (current_macro == 0)
_rl_abort_internal ();

View file

@ -129,8 +129,8 @@ extern int _rl_suppress_redisplay;
extern char *rl_display_prompt;
/* Variables imported from complete.c. */
extern char *rl_completer_word_break_characters;
extern char *rl_basic_word_break_characters;
extern const char *rl_completer_word_break_characters;
extern const char *rl_basic_word_break_characters;
extern int rl_completion_query_items;
extern int rl_complete_with_tilde_expansion;
@ -181,7 +181,7 @@ extern char *xmalloc (), *xrealloc ();
/* */
/* **************************************************************** */
char *rl_library_version = RL_LIBRARY_VERSION;
const char *rl_library_version = RL_LIBRARY_VERSION;
/* A pointer to the keymap that is currently in use.
By default, it is the standard emacs keymap. */
@ -960,8 +960,7 @@ rl_universal_argument (count, key)
way that you should do insertion. rl_insert () calls this
function. */
int
rl_insert_text (string)
char *string;
rl_insert_text (const char *string)
{
register int i, l = strlen (string);

View file

@ -60,7 +60,7 @@ extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
char *name;
const char *name;
Function *function;
} FUNMAP;
@ -286,7 +286,7 @@ extern int rl_translate_keyseq __P((char *, char *, int *));
extern char *rl_untranslate_keyseq __P((int));
extern Function *rl_named_function __P((char *));
extern Function *rl_function_of_keyseq __P((char *, Keymap, int *));
extern Function *rl_function_of_keyseq __P((const char *, Keymap, int *));
extern void rl_list_funmap_names __P((void));
extern char **rl_invoking_keyseqs_in_map __P((Function *, Keymap));
@ -296,7 +296,7 @@ extern void rl_function_dumper __P((int));
extern void rl_macro_dumper __P((int));
extern void rl_variable_dumper __P((int));
extern int rl_read_init_file __P((char *));
extern int rl_read_init_file __P((const char *));
extern int rl_parse_and_bind __P((char *));
/* Functions for manipulating keymaps. */
@ -306,14 +306,14 @@ extern Keymap rl_make_keymap __P((void));
extern void rl_discard_keymap __P((Keymap));
extern Keymap rl_get_keymap_by_name __P((char *));
extern char *rl_get_keymap_name __P((Keymap));
extern const char *rl_get_keymap_name __P((Keymap));
extern void rl_set_keymap __P((Keymap));
extern Keymap rl_get_keymap __P((void));
extern void rl_set_keymap_from_edit_mode __P((void));
extern char *rl_get_keymap_name_from_edit_mode __P((void));
extern const char *rl_get_keymap_name_from_edit_mode __P((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry __P((char *, Function *));
extern int rl_add_funmap_entry __P((const char *, Function *));
extern void rl_initialize_funmap __P((void));
extern char **rl_funmap_names __P((void));
@ -351,7 +351,7 @@ extern void rl_save_prompt __P((void));
extern void rl_restore_prompt __P((void));
/* Modifying text. */
extern int rl_insert_text __P((char *));
extern int rl_insert_text __P((const char *));
extern int rl_delete_text __P((int, int));
extern int rl_kill_text __P((int, int));
extern char *rl_copy_text __P((int, int));
@ -392,9 +392,9 @@ extern int maybe_replace_line __P((void));
extern int rl_complete_internal __P((int));
extern void rl_display_match_list __P((char **, int, int));
extern char **completion_matches __P((char *, CPFunction *));
extern char *username_completion_function __P((char *, int));
extern char *filename_completion_function __P((char *, int));
extern char **completion_matches __P((const char *, CPFunction *));
extern char *username_completion_function __P((const char *, int));
extern char *filename_completion_function __P((const char *, int));
/* **************************************************************** */
/* */
@ -403,11 +403,11 @@ extern char *filename_completion_function __P((char *, int));
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
extern char *rl_library_version;
extern const char *rl_library_version;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern char *rl_readline_name;
extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
@ -506,12 +506,12 @@ extern CPPFunction *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
extern char *rl_basic_word_break_characters;
extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern char *rl_completer_word_break_characters;
extern const char *rl_completer_word_break_characters;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -520,7 +520,7 @@ extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
extern char *rl_basic_quote_characters;
extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern char *rl_filename_quote_characters;

View file

@ -368,13 +368,6 @@ static TIOTYPE otio;
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
static void
rltty_warning (msg)
char *msg;
{
fprintf (stderr, "readline: warning: %s\n", msg);
}
#if defined (_AIX)
void
setopost(tp)
@ -604,8 +597,8 @@ rl_deprep_terminal ()
/* **************************************************************** */
int
rl_restart_output (count, key)
int count, key;
rl_restart_output (int count __attribute__((unused)),
int key __attribute__((unused)))
{
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
@ -637,8 +630,8 @@ rl_restart_output (count, key)
}
int
rl_stop_output (count, key)
int count, key;
rl_stop_output (int count __attribute__((unused)),
int key __attribute__((unused)))
{
int fildes = fileno (rl_instream);

View file

@ -247,8 +247,7 @@ noninc_search (dir, pchar)
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (count, key)
int count, key;
rl_noninc_forward_search (int count __attribute__((unused)), int key)
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
@ -257,8 +256,7 @@ rl_noninc_forward_search (count, key)
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (count, key)
int count, key;
rl_noninc_reverse_search (int count __attribute__((unused)), int key)
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
@ -267,8 +265,8 @@ rl_noninc_reverse_search (count, key)
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_forward_search_again (count, key)
int count, key;
rl_noninc_forward_search_again (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@ -282,8 +280,8 @@ rl_noninc_forward_search_again (count, key)
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_reverse_search_again (count, key)
int count, key;
rl_noninc_reverse_search_again (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@ -352,8 +350,7 @@ rl_history_search_internal (count, direction)
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_forward (count, ignore)
int count, ignore;
rl_history_search_forward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);
@ -366,8 +363,7 @@ rl_history_search_forward (count, ignore)
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_backward (count, ignore)
int count, ignore;
rl_history_search_backward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);

View file

@ -26,6 +26,7 @@
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)

View file

@ -99,8 +99,8 @@ char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
char *term_pc;
char *term_goto, *term_clreol, *term_clrpag, *term_backspace;
char *term_cr, *term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int terminal_can_insert = 0;
@ -245,8 +245,8 @@ rl_resize_terminal ()
}
struct _tc_string {
char *tc_var;
char **tc_value;
const char *tc_var;
char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
@ -291,7 +291,7 @@ get_term_capabilities (bp)
{
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
for (i = 0; i < (int) NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
tcap_initialized = 1;
}
@ -304,7 +304,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = ScreenCols ();
screenheight = ScreenRows ();
screenchars = screenwidth * screenheight;
term_cr = "\r";
term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
@ -322,7 +322,8 @@ _rl_init_terminal_io (terminal_name)
return;
#else /* !__GO32__ */
char *term, *buffer;
const char *term;
char *buffer;
int tty;
Keymap xkeymap;
@ -347,7 +348,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = 79;
screenheight = 24;
screenchars = 79 * 24;
term_cr = "\r";
term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
@ -367,7 +368,7 @@ _rl_init_terminal_io (terminal_name)
UP = term_up;
if (!term_cr)
term_cr = "\r";
term_cr = (char*) "\r";
tty = rl_instream ? fileno (rl_instream) : 0;
@ -427,7 +428,7 @@ rl_get_termcap (cap)
if (tcap_initialized == 0)
return ((char *)NULL);
for (i = 0; i < NUM_TC_STRINGS; i++)
for (i = 0; i < (int) NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);

View file

@ -82,13 +82,13 @@ extern char *get_env_value ();
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
static char *default_prefixes[] =
static const char *default_prefixes[] =
{ " ~", "\t~", (char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
static char *default_suffixes[] =
static const char *default_suffixes[] =
{ " ", "\n", (char *)NULL };
/* If non-null, this contains the address of a function that the application
@ -106,12 +106,12 @@ CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
char **tilde_additional_prefixes = default_prefixes;
const char ** tilde_additional_prefixes = default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
char **tilde_additional_suffixes = default_suffixes;
const char **tilde_additional_suffixes = default_suffixes;
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
@ -122,7 +122,7 @@ tilde_find_prefix (string, len)
int *len;
{
register int i, j, string_len;
register char **prefixes = tilde_additional_prefixes;
register const char **prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
@ -154,7 +154,7 @@ tilde_find_suffix (string)
char *string;
{
register int i, j, string_len;
register char **suffixes;
register const char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);

View file

@ -48,12 +48,12 @@ extern CPFunction *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
extern char **tilde_additional_prefixes;
extern const char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
extern char **tilde_additional_suffixes;
extern const char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand ();

View file

@ -174,7 +174,7 @@ _rl_fix_last_undo_of_type (type, start, end)
for (rl = rl_undo_list; rl; rl = rl->next)
{
if (rl->what == type)
if ((int) rl->what == type)
{
rl->start = start;
rl->end = end;
@ -225,8 +225,8 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */
int
rl_revert_line (count, key)
int count, key;
rl_revert_line (int count __attribute__((unused)),
int key __attribute__((unused)))
{
if (!rl_undo_list)
ding ();
@ -240,8 +240,7 @@ rl_revert_line (count, key)
/* Do some undoing of things that were done. */
int
rl_undo_command (count, key)
int count, key;
rl_undo_command (int count, int key __attribute__((unused)))
{
if (count < 0)
return 0; /* Nothing to do. */

View file

@ -81,7 +81,7 @@ extern char *xmalloc (), *xrealloc ();
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
static char *pathname_alphabetic_chars = "/-_=~.#$";
static const char *pathname_alphabetic_chars = "/-_=~.#$";
int
alphabetic (c)
@ -113,15 +113,15 @@ _rl_abort_internal ()
}
int
rl_abort (count, key)
int count, key;
rl_abort (int count __attribute__((unused)),
int key __attribute__((unused)))
{
return (_rl_abort_internal ());
}
int
rl_tty_status (count, key)
int count, key;
rl_tty_status (int count __attribute__((unused)),
int key __attribute__((unused)))
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
@ -170,8 +170,8 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */
int
rl_tilde_expand (ignore, key)
int ignore, key;
rl_tilde_expand (int ignore __attribute__((unused)),
int key __attribute__((unused)))
{
register int start, end;
char *homedir, *temp;

View file

@ -98,7 +98,7 @@ extern int rl_vi_check ();
static int _rl_vi_doing_insert;
/* Command keys which do movement for xxx_to commands. */
static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
@ -126,7 +126,7 @@ static int _rl_vi_last_key_before_insert;
static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
/* Arrays for the saved marks. */
static int vi_mark_chars[27];

View file

@ -145,7 +145,8 @@ sub new
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'left_outer_join'} = 1; # Supports left outer joins
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
$limits{'limit'} = 1; # supports the limit attribute
$limits{'limit'} = 1; # supports the limit attribute
$limits{'truncate_table'} = 1;
$limits{'load_data_infile'} = 1; # Has load data infile
$limits{'lock_tables'} = 1; # Has lock tables
$limits{'max_column_name'} = 64; # max table and column name
@ -604,6 +605,7 @@ sub new
$limits{'select_without_from'}= 1;
$limits{'subqueries'} = 1;
$limits{'table_wildcard'} = 1;
$limits{'truncate_table'} = 1;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'working_all_fields'} = 1;
$limits{'working_blobs'} = 1; # If big varchar/blobs works
@ -1386,6 +1388,7 @@ sub new
$limits{'max_index_parts'} = 16; # Max segments/key
$limits{'max_column_name'} = 32; # max table and column name
$limits{'truncate_table'} = 1;
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'load_data_infile'} = 0; # Has load data infile
$limits{'lock_tables'} = 0; # Has lock tables

View file

@ -1173,7 +1173,7 @@ if (!$opt_skip_delete)
}
$end_time=new Benchmark;
print "Time for delete_all ($count): " .
print "Time for delete_range ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
if ($opt_lock_tables)
@ -1209,6 +1209,7 @@ print "Insert into table with $keys keys and with a primary key with $seg parts\
# Make keys on the most important types
@types=(0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1); # A 1 for each char field
push(@fields,"field1 tinyint not null");
push(@fields,"field_search tinyint not null");
push(@fields,"field2 mediumint not null");
push(@fields,"field3 smallint not null");
push(@fields,"field4 char(16) not null");
@ -1228,9 +1229,10 @@ for ($i= 1 ; $i <= $seg ; $i++)
}
substr($query,-1)=")";
push (@keys,$query);
push (@keys,"index index2 (field_search)");
#Create other keys
for ($i=2 ; $i <= $keys ; $i++)
for ($i=3 ; $i <= $keys ; $i++)
{
push(@keys,"index index$i (field$i)");
}
@ -1256,11 +1258,11 @@ if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value
$res=$query;
for ($i=0; $i < $many_keys_loop_count; $i++)
{
$id= $i & 127;
$rand=$random[$i];
$tmp="(" . ($i & 127) . ",$rand," . ($i & 32766) .
",'ABCDEF$rand',0,";
$tmp="($id,$id,$rand," . ($i & 32766) . ",'ABCDEF$rand',0,";
for ($j=5; $j <= $fields ; $j++)
for ($j=6; $j <= $fields ; $j++)
{
$tmp.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@ -1281,11 +1283,12 @@ else
{
for ($i=0; $i < $many_keys_loop_count; $i++)
{
$id= $i & 127;
$rand=$random[$i];
$query="insert into bench1 values (" . ($i & 127) . ",$rand," . ($i & 32767) .
$query="insert into bench1 values ($id,$id,$rand," . ($i & 32767) .
",'ABCDEF$rand',0,";
for ($j=5; $j <= $fields ; $j++)
for ($j=6; $j <= $fields ; $j++)
{
$query.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@ -1324,8 +1327,8 @@ print "Testing update of keys\n";
$loop_time=new Benchmark;
for ($i=0 ; $i< 256; $i++)
{
$dbh->do("update bench1 set field5=1 where field1=$i")
or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field1=$i\n";
$dbh->do("update bench1 set field5=1 where field_search=$i")
or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field_search=$i\n";
}
$end_time=new Benchmark;
print "Time for update_of_primary_key_many_keys (256): " .
@ -1366,29 +1369,31 @@ $count=0;
for ($i=0 ; $i < 128 ; $i++)
{
$count++;
$dbh->do("delete from bench1 where field1 = $i") or die $DBI::errstr;
$dbh->do("delete from bench1 where field_search = $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for delete_big_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
if ($opt_lock_tables)
{
$sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
}
print "Deleting everything from table\n";
$count=1;
if ($opt_fast)
{
$dbh->do("delete from bench1") or die $DBI::errstr;
$query= ($limits->{'truncate_table'} ? "truncate table bench1" :
"delete from bench1");
$dbh->do($query) or die $DBI::errstr;
}
else
{
$dbh->do("delete from bench1 where field1 > 0") or die $DBI::errstr;
}
if ($opt_lock_tables)
{
$sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for delete_all_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";

View file

@ -48,27 +48,36 @@ init_query();
print "Wisconsin benchmark test\n\n";
if (!$opt_skip_create)
if ($opt_skip_create)
{
$loop_time= new Benchmark;
for($ti = 0; $ti <= $#table_names; $ti++)
if ($opt_lock_tables)
{
my $table_name = $table_names[$ti];
my $array_ref = $tables[$ti];
# This may fail if we have no table so do not check answer
$sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
print "Creating table $table_name\n" if ($opt_verbose);
do_many($dbh,@$array_ref);
@tmp=@table_names; push(@tmp,@extra_names);
$sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for create_table ($#tables): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
goto start_benchmark;
}
if ($opt_fast && defined($server->{vacuum}))
{
$server->vacuum(1,\$dbh);
}
$loop_time= new Benchmark;
for($ti = 0; $ti <= $#table_names; $ti++)
{
my $table_name = $table_names[$ti];
my $array_ref = $tables[$ti];
# This may fail if we have no table so do not check answer
$sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
print "Creating table $table_name\n" if ($opt_verbose);
do_many($dbh,@$array_ref);
}
$end_time=new Benchmark;
print "Time for create_table ($#tables): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
if ($opt_fast && defined($server->{vacuum}))
{
$server->vacuum(1,\$dbh);
}
####
@ -159,13 +168,6 @@ $sth = $dbh->do("delete from Bprime where Bprime.unique2 >= 1000") or
$end_time=new Benchmark;
print "Time to delete_big (1): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
elsif ($opt_lock_tables)
{
@tmp=@table_names; push(@tmp,@extra_names);
$sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
die $DBI::errstr;
}
if ($opt_fast && defined($server->{vacuum}))
{
@ -176,7 +178,9 @@ if ($opt_fast && defined($server->{vacuum}))
#### Running the benchmark
####
print "Running actual benchmark\n";
start_benchmark:
print "Running the actual benchmark\n";
$loop_time= new Benchmark;
$count=0;

View file

@ -248,7 +248,7 @@ void Field::copy_from_tmp(int row_offset)
}
bool Field::send(String *packet)
bool Field::send(THD *thd, String *packet)
{
if (is_null())
return net_store_null(packet);
@ -256,7 +256,7 @@ bool Field::send(String *packet)
String tmp(buff,sizeof(buff));
val_str(&tmp,&tmp);
CONVERT *convert;
if ((convert=current_thd->convert_set))
if ((convert=thd->convert_set))
return convert->store(packet,tmp.ptr(),tmp.length());
return net_store_data(packet,tmp.ptr(),tmp.length());
}

View file

@ -154,7 +154,7 @@ public:
ptr-=row_offset;
return tmp;
}
bool send(String *packet);
bool send(THD *thd, String *packet);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
uint length=pack_length();

View file

@ -37,15 +37,13 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
/* functions defined in this file */
static char **make_char_array(register uint fields, uint length, myf my_flag);
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
uchar * *sort_keys,
BUFFPEK *buffpek,uint *maxbuffer,
uchar * *sort_keys, IO_CACHE *buffer_file,
IO_CACHE *tempfile,IO_CACHE *indexfile);
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
uint count,BUFFPEK *buffpek,
IO_CACHE *tempfile);
static void make_sortkey(SORTPARAM *param,uchar *to,
byte *ref_pos);
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
static void make_sortkey(SORTPARAM *param,uchar *to, byte *ref_pos);
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
BUFFPEK *buffpek,
uint maxbuffer,IO_CACHE *tempfile,
@ -70,11 +68,12 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
ha_rows *examined_rows)
{
int error;
uint memavl,old_memavl,maxbuffer,skr;
ulong memavl;
uint maxbuffer,skr;
BUFFPEK *buffpek;
ha_rows records;
uchar **sort_keys;
IO_CACHE tempfile,*selected_records_file,*outfile;
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
SORTPARAM param;
DBUG_ENTER("filesort");
DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special););
@ -84,8 +83,10 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
outfile= table->io_cache;
my_b_clear(&tempfile);
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
my_b_clear(&buffpek_pointers);
buffpek=0;
sort_keys= (uchar **) NULL;
error= 1;
bzero((char*) &param,sizeof(param));
param.ref_length= table->file->ref_length;
param.sort_length=sortlength(sortorder,s_length)+ param.ref_length;
@ -136,51 +137,34 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
memavl=sortbuff_size;
while (memavl >= MIN_SORT_MEMORY)
{
if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
(ulonglong) memavl)
param.keys=(uint) records+1;
else
{
maxbuffer=1;
do
{
skr=maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer)
{
my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
goto err;
}
param.keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(param.sort_length+sizeof(char*));
}
while ((maxbuffer= (uint) (records/param.keys+1)) != skr);
}
if ((sort_keys= (uchar **) make_char_array(param.keys,param.sort_length,
ulong old_memavl;
ulong keys= memavl/(param.sort_length+sizeof(char*));
param.keys=(uint) min(records+1, keys);
if ((sort_keys= (uchar **) make_char_array(param.keys, param.sort_length,
MYF(0))))
if ((buffpek = (BUFFPEK*) my_malloc((uint) sizeof(BUFFPEK)*
(maxbuffer+10),
MYF(0))))
break;
else
my_free((gptr) sort_keys,MYF(0));
break;
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
memavl=MIN_SORT_MEMORY;
}
param.keys--;
maxbuffer+=10; /* Some extra range */
if (memavl < MIN_SORT_MEMORY)
{
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
goto err;
}
if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
param.keys--;
param.sort_form= table;
param.end=(param.local_sortorder=sortorder)+s_length;
if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
if ((records=find_all_keys(&param,select,sort_keys, &buffpek_pointers,
&tempfile, selected_records_file)) ==
HA_POS_ERROR)
goto err;
maxbuffer= my_b_tell(&buffpek_pointers)/sizeof(*buffpek);
if (maxbuffer == 0) // The whole set is in memory
{
if (save_index(&param,sort_keys,(uint) records))
@ -188,6 +172,9 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
else
{
if (!(buffpek=read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
goto err;
close_cached_file(&buffpek_pointers);
/* Open cached file if it isn't open */
if (! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
@ -195,8 +182,13 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
goto err;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
/*
Use also the space previously used by string pointers in sort_buffer
for temporary key storage.
*/
param.keys=((param.keys*(param.sort_length+sizeof(char*))) /
param.sort_length-1);
maxbuffer--; // Offset from 0
if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
&tempfile))
goto err;
@ -219,6 +211,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
x_free((gptr) sort_keys);
x_free((gptr) buffpek);
close_cached_file(&tempfile);
close_cached_file(&buffpek_pointers);
if (my_b_inited(outfile))
{
if (flush_io_cache(outfile))
@ -263,11 +256,33 @@ static char **make_char_array(register uint fields, uint length, myf my_flag)
} /* make_char_array */
/* Read all buffer pointers into memory */
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
{
ulong length;
BUFFPEK *tmp;
DBUG_ENTER("read_buffpek_from_file");
tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME));
if (tmp)
{
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
my_b_read(buffpek_pointers, (char*) tmp, length))
{
my_free((char*) tmp, MYF(0));
tmp=0;
}
}
DBUG_RETURN(tmp);
}
/* Search after sort_keys and place them in a temp. file */
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
uchar **sort_keys,
BUFFPEK *buffpek, uint *maxbuffer,
IO_CACHE *buffpek_pointers,
IO_CACHE *tempfile, IO_CACHE *indexfile)
{
int error,flag,quick_select;
@ -349,9 +364,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
{
if (idx == param->keys)
{
if (indexpos >= *maxbuffer ||
write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
DBUG_RETURN(HA_POS_ERROR);
if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
DBUG_RETURN(HA_POS_ERROR);
idx=0; indexpos++;
if (param->ref_length == param->sort_length &&
my_b_tell(tempfile)/param->sort_length >= param->max_rows)
@ -373,11 +387,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
}
if (indexpos)
if (indexpos >= *maxbuffer ||
write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
*maxbuffer=indexpos;
if (indexpos &&
write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
DBUG_RETURN(my_b_inited(tempfile) ?
(ha_rows) (my_b_tell(tempfile)/param->sort_length) :
idx);
@ -387,9 +399,10 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
/* Skriver en buffert med nycklar till filen */
static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
BUFFPEK *buffpek, IO_CACHE *tempfile)
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
{
uint sort_length;
BUFFPEK buffpek;
DBUG_ENTER("write_keys");
sort_length=param->sort_length;
@ -401,15 +414,20 @@ static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
MYF(MY_WME)))
DBUG_RETURN(1); /* purecov: inspected */
buffpek->file_pos=my_b_tell(tempfile);
goto err; /* purecov: inspected */
buffpek.file_pos=my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
buffpek->count=(ha_rows) count;
buffpek.count=(ha_rows) count;
for (uchar **end=sort_keys+count ; sort_keys != end ; sort_keys++)
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
DBUG_RETURN(1);
goto err;
if (my_b_write(buffpek_pointers, (char*) &buffpek, sizeof(buffpek)))
goto err;
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
} /* write_keys */

View file

@ -569,19 +569,19 @@ void Item_varbinary::make_field(Send_field *tmp_field)
** pack data in buffer for sending
*/
bool Item::send(String *packet)
bool Item::send(THD *thd, String *packet)
{
char buff[MAX_FIELD_WIDTH];
CONVERT *convert;
String s(buff,sizeof(buff)),*res;
if (!(res=val_str(&s)))
return net_store_null(packet);
CONVERT *convert;
if ((convert=current_thd->convert_set))
if ((convert=thd->convert_set))
return convert->store(packet,res->ptr(),res->length());
return net_store_data(packet,res->ptr(),res->length());
}
bool Item_null::send(String *packet)
bool Item_null::send(THD *thd, String *packet)
{
return net_store_null(packet);
}

View file

@ -56,7 +56,7 @@ public:
virtual bool save_in_field(Field *field);
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); }
virtual bool send(String *str);
virtual bool send(THD *thd, String *str);
virtual bool eq(const Item *) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0;
@ -118,7 +118,7 @@ public:
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
bool send(String *str_arg) { return result_field->send(str_arg); }
bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); }
void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field);
@ -149,7 +149,7 @@ public:
bool save_in_field(Field *field);
enum Item_result result_type () const
{ return STRING_RESULT; }
bool send(String *str);
bool send(THD *thd, String *str);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; }
@ -346,7 +346,7 @@ public:
{
return (null_value=(*ref)->get_date(ltime,fuzzydate));
}
bool send(String *tmp) { return (*ref)->send(tmp); }
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *,struct st_table_list *);
bool save_in_field(Field *field) { return (*ref)->save_in_field(field); }

View file

@ -898,7 +898,10 @@ public:
const char *func_name() const { return "match_nl"; }
double val();
int ft_handler_init(const byte *query, uint querylen, bool presort)
{ ft_handler=table->file->ft_init_ext(FT_NL,key, query, querylen, presort); }
{
ft_handler=table->file->ft_init_ext(FT_NL,key, query, querylen, presort);
return 0;
}
};
class Item_func_match_bool :public Item_func_match
@ -908,6 +911,9 @@ public:
const char *func_name() const { return "match_bool"; }
double val();
int ft_handler_init(const byte *query, uint querylen, bool presort)
{ ft_handler=table->file->ft_init_ext(FT_BOOL,key, query, querylen, presort); }
{
ft_handler=table->file->ft_init_ext(FT_BOOL,key, query, querylen, presort);
return 0;
}
};

View file

@ -280,20 +280,21 @@ public:
typedef struct st_qsel_param {
uint baseflag,keys,max_key_part;
table_map prev_tables,read_tables,current_table;
TABLE *table;
bool quick; // Don't calulate possible keys
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
MEM_ROOT *mem_root;
table_map prev_tables,read_tables,current_table;
uint baseflag,keys,max_key_part;
uint real_keynr[MAX_KEY];
char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
bool quick; // Don't calulate possible keys
} PARAM;
static SEL_TREE * get_mm_parts(PARAM *param,Field *field,
Item_func::Functype type,Item *value,
Item_result cmp_type);
static SEL_ARG *get_mm_leaf(Field *field,KEY_PART *key_part,
static SEL_ARG *get_mm_leaf(PARAM *param,Field *field,KEY_PART *key_part,
Item_func::Functype type,Item *value);
static bool like_range(const char *ptr,uint length,char wild_prefix,
uint field_length, char *min_str,char *max_str,
@ -626,6 +627,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
param.current_table= head->map;
param.table=head;
param.keys=0;
param.mem_root= &alloc;
current_thd->no_errors=1; // Don't warn about NULL
init_sql_alloc(&alloc,2048,0);
@ -894,7 +896,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
tree=new SEL_TREE();
if (!value || !(value->used_tables() & ~param->read_tables))
{
sel_arg=get_mm_leaf(key_part->field,key_part,type,value);
sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
if (!sel_arg)
continue;
if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
@ -914,7 +916,7 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
static SEL_ARG *
get_mm_leaf(Field *field,KEY_PART *key_part,
get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
Item_func::Functype type,Item *value)
{
uint maybe_null=(uint) field->real_maybe_null();
@ -959,7 +961,7 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
field_length=length;
}
length+=offset;
if (!(min_str= (char*) sql_alloc(length*2)))
if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
DBUG_RETURN(0);
max_str=min_str+length;
if (maybe_null)
@ -1026,7 +1028,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
if (type == Item_func::EQUAL_FUNC)
{
/* convert column_name <=> NULL -> column_name IS NULL */
char *str= (char*) sql_alloc(1); // Get local copy of key
// Get local copy of key
char *str= (char*) alloc_root(param->mem_root,1);
if (!*str)
DBUG_RETURN(0);
*str = 1;
@ -1035,7 +1038,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
DBUG_RETURN(&null_element); // NULL is never true
}
// Get local copy of key
char *str= (char*) sql_alloc(key_part->part_length+maybe_null);
char *str= (char*) alloc_root(param->mem_root,
key_part->part_length+maybe_null);
if (!str)
DBUG_RETURN(0);
if (maybe_null)
@ -2235,7 +2239,7 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
else
{
quick->key_parts=(KEY_PART*)
sql_memdup(param->key[idx],
memdup_root(&quick->alloc,(char*) param->key[idx],
sizeof(KEY_PART)*
param->table->key_info[param->real_keynr[idx]].key_parts);
}
@ -2406,7 +2410,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
(key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
sql_alloc(sizeof(KEY_PART)*ref->key_parts)))
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
goto err;
for (part=0 ; part < ref->key_parts ;part++,key_part++)

View file

@ -292,7 +292,7 @@ bool select_send::send_data(List<Item> &items)
Item *item;
while ((item=li++))
{
if (item->send(packet))
if (item->send(thd, packet))
{
packet->free(); // Free used
my_error(ER_OUT_OF_RESOURCES,MYF(0));

View file

@ -385,7 +385,9 @@ public:
}
inline char *strdup(const char *str)
{ return strdup_root(&mem_root,str); }
inline char *memdup(const char *str, unsigned int size)
inline char *strmake(const char *str, uint size)
{ return strmake_root(&mem_root,str,size); }
inline char *memdup(const char *str, uint size)
{ return memdup_root(&mem_root,str,size); }
};

View file

@ -202,7 +202,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
it.rewind();
while ((item=it++))
{
if (item->send(packet))
if (item->send(thd,packet))
{
packet->free(); // Free used
my_error(ER_OUT_OF_RESOURCES,MYF(0));

View file

@ -201,7 +201,7 @@ LEX_STRING get_token(LEX *lex,uint length)
LEX_STRING tmp;
yyUnget(); // ptr points now after last token char
tmp.length=lex->yytoklen=length;
tmp.str=(char*) sql_strmake((char*) lex->tok_start,tmp.length);
tmp.str=(char*) lex->thd->strmake((char*) lex->tok_start,tmp.length);
return tmp;
}
@ -250,7 +250,7 @@ static char *get_text(LEX *lex)
str=lex->tok_start+1;
end=lex->ptr-1;
if (!(start=(uchar*) sql_alloc((uint) (end-str)+1)))
if (!(start=(uchar*) lex->thd->alloc((uint) (end-str)+1)))
return (char*) ""; // Sql_alloc has set error flag
if (!found_escape)
{

View file

@ -2049,10 +2049,11 @@ get_best_combination(JOIN *join)
KEYUSE *keyuse;
KEY *keyinfo;
uint table_count;
THD *thd=join->thd;
table_count=join->tables;
if (!(join->join_tab=join_tab=
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB)*table_count)))
(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
return TRUE;
join->const_tables=0; /* for checking */
@ -2130,10 +2131,10 @@ get_best_combination(JOIN *join)
j->ref.key_parts=keyparts;
j->ref.key_length=length;
j->ref.key=(int) key;
if (!(j->ref.key_buff= (byte*) sql_calloc(ALIGN_SIZE(length)*2)) ||
!(j->ref.key_copy= (store_key**) sql_alloc((sizeof(store_key*) *
if (!(j->ref.key_buff= (byte*) thd->calloc(ALIGN_SIZE(length)*2)) ||
!(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
(keyparts+1)))) ||
!(j->ref.items= (Item**) sql_alloc(sizeof(Item*)*keyparts)))
!(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)))
{
return TRUE;
}
@ -2153,7 +2154,6 @@ get_best_combination(JOIN *join)
}
else
{
THD *thd=join->thd;
for (i=0 ; i < keyparts ; keyuse++,i++)
{
while (keyuse->keypart != i ||
@ -2358,7 +2358,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name););
SQL_SELECT *sel=tab->select=(SQL_SELECT*)
sql_memdup((gptr) select, sizeof(SQL_SELECT));
join->thd->memdup((gptr) select, sizeof(SQL_SELECT));
if (!sel)
DBUG_RETURN(1); // End of memory
tab->select_cond=sel->cond=tmp;
@ -2439,8 +2439,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
current_map)))
{
DBUG_EXECUTE("where",print_where(tmp,"cache"););
tab->cache.select=(SQL_SELECT*) sql_memdup((gptr) sel,
sizeof(SQL_SELECT));
tab->cache.select=(SQL_SELECT*)
join->thd->memdup((gptr) sel, sizeof(SQL_SELECT));
tab->cache.select->cond=tmp;
tab->cache.select->read_tables=join->const_table_map;
}

View file

@ -92,7 +92,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}

View file

@ -106,7 +106,7 @@ $running_insert_threads=$opt_threads+$numtables;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
if ($work{$pid} =~ /^insert/)
{
if (!--$running_insert_threads)

View file

@ -56,7 +56,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}

View file

@ -79,7 +79,7 @@ print "Total time: " .
exit(0);
#
# Insert records in the table. Delete table when test is finnished
# Insert records in the table. Delete table when test is finished
#
sub test_insert

View file

@ -65,7 +65,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}