diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-13 02:25:53 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-13 02:25:53 +0000 |
commit | 7465dbcf2a4c0a0983d40e5c0f5c057d2ed04125 (patch) | |
tree | fdbbbaab05b45dfb3f67e62e23863e4cc899584b | |
parent | f78a656f7c287c0963d985490b3e77751b4a81bc (diff) | |
download | busybox-w32-7465dbcf2a4c0a0983d40e5c0f5c057d2ed04125.tar.gz busybox-w32-7465dbcf2a4c0a0983d40e5c0f5c057d2ed04125.tar.bz2 busybox-w32-7465dbcf2a4c0a0983d40e5c0f5c057d2ed04125.zip |
ash: speed up NOFORK code in ash by eliminating second find_applet().
some code reduction along the way.
function old new delta
run_list 1971 1981 +10
run_nofork_applet_prime 181 182 +1
unsetcmd 97 96 -1
delete_cmd_entry 54 53 -1
describe_command 399 397 -2
cmdlookup 152 150 -2
evaltreenr 602 599 -3
evaltree 602 599 -3
clearcmdentry 101 98 -3
cdcmd 675 672 -3
hashcmd 305 301 -4
find_command 933 910 -23
evalcommand 1371 1229 -142
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/11 up/down: 11/-187) Total: -176 bytes
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 11 | ||||
-rw-r--r-- | shell/ash.c | 44 | ||||
-rw-r--r-- | shell/hush.c | 2 |
3 files changed, 34 insertions, 23 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 1567d89be..2c4c930b2 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -146,6 +146,15 @@ int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char ** | |||
146 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 146 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
147 | /* Finally we can call NOFORK applet's main() */ | 147 | /* Finally we can call NOFORK applet's main() */ |
148 | rc = applet_main[applet_no](argc, tmp_argv); | 148 | rc = applet_main[applet_no](argc, tmp_argv); |
149 | |||
150 | /* The whole reason behind nofork_save_area is that <applet>_main | ||
151 | * may exit non-locally! For example, in hush Ctrl-Z tries to | ||
152 | * (modulo bugs) to dynamically create child (backgrounded task) | ||
153 | * if it detects that Ctrl-Z was pressed when a NOFORK was running! | ||
154 | * Testcase: interactive "rm -i". | ||
155 | * Don't fool yourself into thinking "and <applet>_main() returns | ||
156 | * quickly here" and removing "useless" nofork_save_area code. */ | ||
157 | |||
149 | } else { /* xfunc died in NOFORK applet */ | 158 | } else { /* xfunc died in NOFORK applet */ |
150 | /* in case they meant to return 0... */ | 159 | /* in case they meant to return 0... */ |
151 | if (rc == -2222) | 160 | if (rc == -2222) |
@@ -154,7 +163,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char ** | |||
154 | 163 | ||
155 | /* Restoring globals */ | 164 | /* Restoring globals */ |
156 | restore_nofork_data(old); | 165 | restore_nofork_data(old); |
157 | return rc; | 166 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ |
158 | } | 167 | } |
159 | 168 | ||
160 | int run_nofork_applet(int applet_no, char **argv) | 169 | int run_nofork_applet(int applet_no, char **argv) |
diff --git a/shell/ash.c b/shell/ash.c index cc61401d1..409d084cf 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6828,9 +6828,13 @@ struct builtincmd { | |||
6828 | #define IS_BUILTIN_ASSIGN(b) ((b)->name[0] & 4) | 6828 | #define IS_BUILTIN_ASSIGN(b) ((b)->name[0] & 4) |
6829 | 6829 | ||
6830 | struct cmdentry { | 6830 | struct cmdentry { |
6831 | int cmdtype; | 6831 | smallint cmdtype; /* CMDxxx */ |
6832 | union param { | 6832 | union param { |
6833 | int index; | 6833 | int index; |
6834 | /* index >= 0 for commands without path (slashes) */ | ||
6835 | /* (TODO: what exactly does the value mean? PATH position?) */ | ||
6836 | /* index == -1 for commands with slashes */ | ||
6837 | /* index == (-2 - applet_no) for NOFORK applets */ | ||
6834 | const struct builtincmd *cmd; | 6838 | const struct builtincmd *cmd; |
6835 | struct funcnode *func; | 6839 | struct funcnode *func; |
6836 | } u; | 6840 | } u; |
@@ -6867,7 +6871,7 @@ static void find_command(char *, struct cmdentry *, int, const char *); | |||
6867 | struct tblentry { | 6871 | struct tblentry { |
6868 | struct tblentry *next; /* next entry in hash chain */ | 6872 | struct tblentry *next; /* next entry in hash chain */ |
6869 | union param param; /* definition of builtin function */ | 6873 | union param param; /* definition of builtin function */ |
6870 | short cmdtype; /* index identifying command */ | 6874 | smallint cmdtype; /* CMDxxx */ |
6871 | char rehash; /* if set, cd done since entry created */ | 6875 | char rehash; /* if set, cd done since entry created */ |
6872 | char cmdname[ARB]; /* name of command */ | 6876 | char cmdname[ARB]; /* name of command */ |
6873 | }; | 6877 | }; |
@@ -7355,7 +7359,7 @@ describe_command(char *command, int describe_command_verbose) | |||
7355 | case CMDNORMAL: { | 7359 | case CMDNORMAL: { |
7356 | int j = entry.u.index; | 7360 | int j = entry.u.index; |
7357 | char *p; | 7361 | char *p; |
7358 | if (j == -1) { | 7362 | if (j < 0) { |
7359 | p = command; | 7363 | p = command; |
7360 | } else { | 7364 | } else { |
7361 | do { | 7365 | do { |
@@ -8747,22 +8751,17 @@ evalcommand(union node *cmd, int flags) | |||
8747 | /* Execute the command. */ | 8751 | /* Execute the command. */ |
8748 | switch (cmdentry.cmdtype) { | 8752 | switch (cmdentry.cmdtype) { |
8749 | default: | 8753 | default: |
8750 | |||
8751 | #if ENABLE_FEATURE_SH_NOFORK | 8754 | #if ENABLE_FEATURE_SH_NOFORK |
8752 | { | 8755 | { |
8753 | /* TODO: don't rerun find_applet_by_name, find_command | 8756 | /* find_command() encodes applet_no as (-2 - applet_no) */ |
8754 | * already did it. Make it save applet_no somewhere */ | 8757 | int applet_no = (- cmdentry.u.index - 2); |
8755 | int applet_no = find_applet_by_name(argv[0]); | ||
8756 | if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { | 8758 | if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { |
8757 | struct nofork_save_area nofork_save; | ||
8758 | |||
8759 | listsetvar(varlist.list, VEXPORT|VSTACK); | 8759 | listsetvar(varlist.list, VEXPORT|VSTACK); |
8760 | save_nofork_data(&nofork_save); | 8760 | /* run <applet>_main() */ |
8761 | /* run <applet>_main(), then restore nofork_save_area */ | 8761 | exitstatus = run_nofork_applet(applet_no, argv); |
8762 | exitstatus = run_nofork_applet_prime(&nofork_save, applet_no, argv) & 0xff; | ||
8763 | break; | 8762 | break; |
8764 | } | 8763 | } |
8765 | } | 8764 | } |
8766 | #endif | 8765 | #endif |
8767 | 8766 | ||
8768 | /* Fork off a child process if necessary. */ | 8767 | /* Fork off a child process if necessary. */ |
@@ -11618,10 +11617,13 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
11618 | } | 11617 | } |
11619 | 11618 | ||
11620 | #if ENABLE_FEATURE_SH_STANDALONE | 11619 | #if ENABLE_FEATURE_SH_STANDALONE |
11621 | if (find_applet_by_name(name) >= 0) { | 11620 | { |
11622 | entry->cmdtype = CMDNORMAL; | 11621 | int applet_no = find_applet_by_name(name); |
11623 | entry->u.index = -1; | 11622 | if (applet_no >= 0) { |
11624 | return; | 11623 | entry->cmdtype = CMDNORMAL; |
11624 | entry->u.index = -2 - applet_no; | ||
11625 | return; | ||
11626 | } | ||
11625 | } | 11627 | } |
11626 | #endif | 11628 | #endif |
11627 | 11629 | ||
@@ -12691,7 +12693,7 @@ is_right_associativity(operator prec) | |||
12691 | || prec == PREC(TOK_CONDITIONAL)); | 12693 | || prec == PREC(TOK_CONDITIONAL)); |
12692 | } | 12694 | } |
12693 | 12695 | ||
12694 | typedef struct ARITCH_VAR_NUM { | 12696 | typedef struct { |
12695 | arith_t val; | 12697 | arith_t val; |
12696 | arith_t contidional_second_val; | 12698 | arith_t contidional_second_val; |
12697 | char contidional_second_val_initialized; | 12699 | char contidional_second_val_initialized; |
@@ -12699,9 +12701,9 @@ typedef struct ARITCH_VAR_NUM { | |||
12699 | else is variable name */ | 12701 | else is variable name */ |
12700 | } v_n_t; | 12702 | } v_n_t; |
12701 | 12703 | ||
12702 | typedef struct CHK_VAR_RECURSIVE_LOOPED { | 12704 | typedef struct chk_var_recursive_looped_t { |
12703 | const char *var; | 12705 | const char *var; |
12704 | struct CHK_VAR_RECURSIVE_LOOPED *next; | 12706 | struct chk_var_recursive_looped_t *next; |
12705 | } chk_var_recursive_looped_t; | 12707 | } chk_var_recursive_looped_t; |
12706 | 12708 | ||
12707 | static chk_var_recursive_looped_t *prev_chk_var_recursive; | 12709 | static chk_var_recursive_looped_t *prev_chk_var_recursive; |
diff --git a/shell/hush.c b/shell/hush.c index 545367cb6..aa740f1b4 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1861,7 +1861,7 @@ static int run_pipe(struct pipe *pi) | |||
1861 | //sp: if (child->sp) | 1861 | //sp: if (child->sp) |
1862 | argv_expanded = expand_strvec_to_strvec(argv + i); | 1862 | argv_expanded = expand_strvec_to_strvec(argv + i); |
1863 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]); | 1863 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]); |
1864 | rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded) & 0xff; | 1864 | rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded); |
1865 | free(argv_expanded); | 1865 | free(argv_expanded); |
1866 | restore_redirects(squirrel); | 1866 | restore_redirects(squirrel); |
1867 | debug_printf_exec("run_pipe return %d\n", rcode); | 1867 | debug_printf_exec("run_pipe return %d\n", rcode); |