diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-02 19:43:34 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
| commit | 71e1fc6b376e1fde2c3b0dbcf94c4261eed9c6c5 (patch) | |
| tree | 0a91702c3dc192b3dead09f39c7946562c952a36 /miscutils | |
| parent | df51539ed0ceaa0556a509b25dafdec11437e645 (diff) | |
| download | busybox-w32-71e1fc6b376e1fde2c3b0dbcf94c4261eed9c6c5.tar.gz busybox-w32-71e1fc6b376e1fde2c3b0dbcf94c4261eed9c6c5.tar.bz2 busybox-w32-71e1fc6b376e1fde2c3b0dbcf94c4261eed9c6c5.zip | |
bc: only check for ^C in bc_program_exec() main loop
Checking it in individual operations such as SQRT is not necessary
since they usually do not take very long to complete. We repeatedly return
to main loop.
TODO: re-add more fine-grained ^C checks - but only with examples where it is
actually needed. E.g. I suspect simplest ops like addition or compare won't need it.
function old new delta
bc_program_index 66 64 -2
bc_num_s 258 246 -12
bc_num_cmp 294 275 -19
bc_num_compare 84 59 -25
bc_num_subArrays 74 47 -27
bc_num_a 474 445 -29
bc_program_exec 4530 4500 -30
bc_num_p 518 472 -46
bc_num_d 604 558 -46
bc_num_k 1005 957 -48
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/10 up/down: 0/-284) Total: -284 bytes
text data bss dec hex filename
988601 485 7296 996382 f341e busybox_old
988317 485 7296 996098 f3302 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 70 |
1 files changed, 21 insertions, 49 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 7e72ab28f..63b745dc7 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
| @@ -1338,12 +1338,12 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt) | |||
| 1338 | #if ENABLE_FEATURE_BC_SIGNALS | 1338 | #if ENABLE_FEATURE_BC_SIGNALS |
| 1339 | if (bb_got_signal) { /* ^C was pressed */ | 1339 | if (bb_got_signal) { /* ^C was pressed */ |
| 1340 | intr: | 1340 | intr: |
| 1341 | bb_got_signal = 0; /* resets G_interrupt to zero */ | ||
| 1341 | fputs(IS_BC | 1342 | fputs(IS_BC |
| 1342 | ? "\ninterrupt (type \"quit\" to exit)\n" | 1343 | ? "\ninterrupt (type \"quit\" to exit)\n" |
| 1343 | : "\ninterrupt (type \"q\" to exit)\n" | 1344 | : "\ninterrupt (type \"q\" to exit)\n" |
| 1344 | , stderr); | 1345 | , stderr); |
| 1345 | } | 1346 | } |
| 1346 | bb_got_signal = 0; /* resets G_interrupt to zero */ | ||
| 1347 | #endif | 1347 | #endif |
| 1348 | if (G.ttyin && !G_posix) | 1348 | if (G.ttyin && !G_posix) |
| 1349 | fputs(prompt, stderr); | 1349 | fputs(prompt, stderr); |
| @@ -1458,25 +1458,23 @@ static void bc_num_ten(BcNum *n) | |||
| 1458 | n->num[1] = 1; | 1458 | n->num[1] = 1; |
| 1459 | } | 1459 | } |
| 1460 | 1460 | ||
| 1461 | static BcStatus bc_num_subArrays(BcDig *restrict a, BcDig *restrict b, | 1461 | static void bc_num_subArrays(BcDig *restrict a, BcDig *restrict b, |
| 1462 | size_t len) | 1462 | size_t len) |
| 1463 | { | 1463 | { |
| 1464 | size_t i, j; | 1464 | size_t i, j; |
| 1465 | for (i = 0; !G_interrupt && i < len; ++i) { | 1465 | for (i = 0; i < len; ++i) { |
| 1466 | for (a[i] -= b[i], j = 0; !G_interrupt && a[i + j] < 0;) { | 1466 | for (a[i] -= b[i], j = 0; a[i + j] < 0;) { |
| 1467 | a[i + j++] += 10; | 1467 | a[i + j++] += 10; |
| 1468 | a[i + j] -= 1; | 1468 | a[i + j] -= 1; |
| 1469 | } | 1469 | } |
| 1470 | } | 1470 | } |
| 1471 | ///move ^C detection to bc_num_binary() (can make bc_num_s() return void) | ||
| 1472 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | ||
| 1473 | } | 1471 | } |
| 1474 | 1472 | ||
| 1475 | static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len) | 1473 | static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len) |
| 1476 | { | 1474 | { |
| 1477 | size_t i; | 1475 | size_t i; |
| 1478 | int c = 0; | 1476 | int c = 0; |
| 1479 | for (i = len - 1; !G_interrupt && i < len && !(c = a[i] - b[i]); --i); | 1477 | for (i = len - 1; i < len && !(c = a[i] - b[i]); --i); |
| 1480 | return BC_NUM_NEG(i + 1, c < 0); | 1478 | return BC_NUM_NEG(i + 1, c < 0); |
| 1481 | } | 1479 | } |
| 1482 | 1480 | ||
| @@ -1522,7 +1520,7 @@ static ssize_t bc_num_cmp(BcNum *a, BcNum *b) | |||
| 1522 | cmp = bc_num_compare(max_num, min_num, b_int + min); | 1520 | cmp = bc_num_compare(max_num, min_num, b_int + min); |
| 1523 | if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg); | 1521 | if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg); |
| 1524 | 1522 | ||
| 1525 | for (max_num -= diff, i = diff - 1; !G_interrupt && i < diff; --i) { | 1523 | for (max_num -= diff, i = diff - 1; i < diff; --i) { |
| 1526 | if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg); | 1524 | if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg); |
| 1527 | } | 1525 | } |
| 1528 | 1526 | ||
| @@ -1681,13 +1679,13 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | |||
| 1681 | ptr = ptr_b; | 1679 | ptr = ptr_b; |
| 1682 | } | 1680 | } |
| 1683 | 1681 | ||
| 1684 | for (carry = 0, i = 0; !G_interrupt && i < min_rdx + min_int; ++i, ++c->len) { | 1682 | for (carry = 0, i = 0; i < min_rdx + min_int; ++i, ++c->len) { |
| 1685 | in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; | 1683 | in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; |
| 1686 | carry = in / 10; | 1684 | carry = in / 10; |
| 1687 | ptr_c[i] = (BcDig)(in % 10); | 1685 | ptr_c[i] = (BcDig)(in % 10); |
| 1688 | } | 1686 | } |
| 1689 | 1687 | ||
| 1690 | for (; !G_interrupt && i < max + min_rdx; ++i, ++c->len) { | 1688 | for (; i < max + min_rdx; ++i, ++c->len) { |
| 1691 | in = ((int) ptr[i]) + carry; | 1689 | in = ((int) ptr[i]) + carry; |
| 1692 | carry = in / 10; | 1690 | carry = in / 10; |
| 1693 | ptr_c[i] = (BcDig)(in % 10); | 1691 | ptr_c[i] = (BcDig)(in % 10); |
| @@ -1695,13 +1693,11 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | |||
| 1695 | 1693 | ||
| 1696 | if (carry != 0) c->num[c->len++] = (BcDig) carry; | 1694 | if (carry != 0) c->num[c->len++] = (BcDig) carry; |
| 1697 | 1695 | ||
| 1698 | ///move ^C detection to bc_num_binary() | 1696 | return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary() |
| 1699 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | ||
| 1700 | } | 1697 | } |
| 1701 | 1698 | ||
| 1702 | static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | 1699 | static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) |
| 1703 | { | 1700 | { |
| 1704 | BcStatus s; | ||
| 1705 | ssize_t cmp; | 1701 | ssize_t cmp; |
| 1706 | BcNum *minuend, *subtrahend; | 1702 | BcNum *minuend, *subtrahend; |
| 1707 | size_t start; | 1703 | size_t start; |
| @@ -1755,11 +1751,11 @@ static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | |||
| 1755 | else | 1751 | else |
| 1756 | start = c->rdx - subtrahend->rdx; | 1752 | start = c->rdx - subtrahend->rdx; |
| 1757 | 1753 | ||
| 1758 | s = bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len); | 1754 | bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len); |
| 1759 | 1755 | ||
| 1760 | bc_num_clean(c); | 1756 | bc_num_clean(c); |
| 1761 | 1757 | ||
| 1762 | return s; | 1758 | return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary() |
| 1763 | } | 1759 | } |
| 1764 | 1760 | ||
| 1765 | static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | 1761 | static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, |
| @@ -1771,8 +1767,6 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
| 1771 | BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp; | 1767 | BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp; |
| 1772 | bool aone = BC_NUM_ONE(a); | 1768 | bool aone = BC_NUM_ONE(a); |
| 1773 | 1769 | ||
| 1774 | ///move ^C detection to bc_num_binary() | ||
| 1775 | if (G_interrupt) return BC_STATUS_EXEC_SIGNAL; | ||
| 1776 | if (a->len == 0 || b->len == 0) { | 1770 | if (a->len == 0 || b->len == 0) { |
| 1777 | bc_num_zero(c); | 1771 | bc_num_zero(c); |
| 1778 | return BC_STATUS_SUCCESS; | 1772 | return BC_STATUS_SUCCESS; |
| @@ -1790,9 +1784,9 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
| 1790 | memset(c->num, 0, sizeof(BcDig) * c->cap); | 1784 | memset(c->num, 0, sizeof(BcDig) * c->cap); |
| 1791 | c->len = carry = len = 0; | 1785 | c->len = carry = len = 0; |
| 1792 | 1786 | ||
| 1793 | for (i = 0; !G_interrupt && i < b->len; ++i) { | 1787 | for (i = 0; i < b->len; ++i) { |
| 1794 | 1788 | ||
| 1795 | for (j = 0; !G_interrupt && j < a->len; ++j) { | 1789 | for (j = 0; j < a->len; ++j) { |
| 1796 | int in = (int) c->num[i + j]; | 1790 | int in = (int) c->num[i + j]; |
| 1797 | in += ((int) a->num[j]) * ((int) b->num[i]) + carry; | 1791 | in += ((int) a->num[j]) * ((int) b->num[i]) + carry; |
| 1798 | carry = in / 10; | 1792 | carry = in / 10; |
| @@ -1806,8 +1800,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
| 1806 | 1800 | ||
| 1807 | c->len = len; | 1801 | c->len = len; |
| 1808 | 1802 | ||
| 1809 | ///move ^C detection to bc_num_binary() | 1803 | return BC_STATUS_SUCCESS; |
| 1810 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | ||
| 1811 | } | 1804 | } |
| 1812 | 1805 | ||
| 1813 | bc_num_init(&l1, max); | 1806 | bc_num_init(&l1, max); |
| @@ -1957,17 +1950,17 @@ static BcStatus bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
| 1957 | c->len = cp.len; | 1950 | c->len = cp.len; |
| 1958 | p = b->num; | 1951 | p = b->num; |
| 1959 | 1952 | ||
| 1960 | for (i = end - 1; !G_interrupt && !s && i < end; --i) { | 1953 | for (i = end - 1; !s && i < end; --i) { |
| 1961 | n = cp.num + i; | 1954 | n = cp.num + i; |
| 1962 | for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q) | 1955 | for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q) |
| 1963 | s = bc_num_subArrays(n, p, len); | 1956 | bc_num_subArrays(n, p, len); |
| 1964 | c->num[i] = q; | 1957 | c->num[i] = q; |
| 1965 | } | 1958 | } |
| 1966 | 1959 | ||
| 1967 | if (!s) bc_num_retireMul(c, scale, a->neg, b->neg); | 1960 | bc_num_retireMul(c, scale, a->neg, b->neg); |
| 1968 | bc_num_free(&cp); | 1961 | bc_num_free(&cp); |
| 1969 | 1962 | ||
| 1970 | return s; | 1963 | return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary() |
| 1971 | } | 1964 | } |
| 1972 | 1965 | ||
| 1973 | static BcStatus bc_num_r(BcNum *a, BcNum *b, BcNum *restrict c, | 1966 | static BcStatus bc_num_r(BcNum *a, BcNum *b, BcNum *restrict c, |
| @@ -2057,21 +2050,15 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
| 2057 | 2050 | ||
| 2058 | b->neg = neg; | 2051 | b->neg = neg; |
| 2059 | 2052 | ||
| 2060 | for (powrdx = a->rdx; !G_interrupt && !(pow & 1); pow >>= 1) { | 2053 | for (powrdx = a->rdx; !(pow & 1); pow >>= 1) { |
| 2061 | powrdx <<= 1; | 2054 | powrdx <<= 1; |
| 2062 | s = bc_num_mul(©, ©, ©, powrdx); | 2055 | s = bc_num_mul(©, ©, ©, powrdx); |
| 2063 | if (s) goto err; | 2056 | if (s) goto err; |
| 2064 | } | 2057 | } |
| 2065 | 2058 | ||
| 2066 | if (G_interrupt) { | ||
| 2067 | ///move ^C detection to bc_num_binary() | ||
| 2068 | s = BC_STATUS_EXEC_SIGNAL; | ||
| 2069 | goto err; | ||
| 2070 | } | ||
| 2071 | |||
| 2072 | bc_num_copy(c, ©); | 2059 | bc_num_copy(c, ©); |
| 2073 | 2060 | ||
| 2074 | for (resrdx = powrdx, pow >>= 1; !G_interrupt && pow != 0; pow >>= 1) { | 2061 | for (resrdx = powrdx, pow >>= 1; pow != 0; pow >>= 1) { |
| 2075 | 2062 | ||
| 2076 | powrdx <<= 1; | 2063 | powrdx <<= 1; |
| 2077 | s = bc_num_mul(©, ©, ©, powrdx); | 2064 | s = bc_num_mul(©, ©, ©, powrdx); |
| @@ -2089,12 +2076,6 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
| 2089 | if (s) goto err; | 2076 | if (s) goto err; |
| 2090 | } | 2077 | } |
| 2091 | 2078 | ||
| 2092 | if (G_interrupt) { | ||
| 2093 | ///move ^C detection to bc_num_binary() | ||
| 2094 | s = BC_STATUS_EXEC_SIGNAL; | ||
| 2095 | goto err; | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | if (c->rdx > scale) bc_num_truncate(c, c->rdx - scale); | 2079 | if (c->rdx > scale) bc_num_truncate(c, c->rdx - scale); |
| 2099 | 2080 | ||
| 2100 | // We can't use bc_num_clean() here. | 2081 | // We can't use bc_num_clean() here. |
| @@ -2140,8 +2121,6 @@ static BcStatus bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale, | |||
| 2140 | 2121 | ||
| 2141 | if (init) bc_num_free(&num2); | 2122 | if (init) bc_num_free(&num2); |
| 2142 | 2123 | ||
| 2143 | ///move ^C detection here: | ||
| 2144 | // if (s == 0 && G_interrupt) s = BC_STATUS_EXEC_SIGNAL; | ||
| 2145 | return s; | 2124 | return s; |
| 2146 | } | 2125 | } |
| 2147 | 2126 | ||
| @@ -2644,8 +2623,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale) | |||
| 2644 | resrdx = scale + 2; | 2623 | resrdx = scale + 2; |
| 2645 | len = BC_NUM_INT(x0) + resrdx - 1; | 2624 | len = BC_NUM_INT(x0) + resrdx - 1; |
| 2646 | 2625 | ||
| 2647 | ///move ^C detection to callers | 2626 | while (cmp != 0 || digs < len) { |
| 2648 | while (!G_interrupt && (cmp != 0 || digs < len)) { | ||
| 2649 | 2627 | ||
| 2650 | s = bc_num_div(a, x0, &f, resrdx); | 2628 | s = bc_num_div(a, x0, &f, resrdx); |
| 2651 | if (s) goto err; | 2629 | if (s) goto err; |
| @@ -2673,12 +2651,6 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale) | |||
| 2673 | x1 = temp; | 2651 | x1 = temp; |
| 2674 | } | 2652 | } |
| 2675 | 2653 | ||
| 2676 | if (G_interrupt) { | ||
| 2677 | ///move ^C detection to callers | ||
| 2678 | s = BC_STATUS_EXEC_SIGNAL; | ||
| 2679 | goto err; | ||
| 2680 | } | ||
| 2681 | |||
| 2682 | bc_num_copy(b, x0); | 2654 | bc_num_copy(b, x0); |
| 2683 | scale -= 1; | 2655 | scale -= 1; |
| 2684 | if (b->rdx > scale) bc_num_truncate(b, b->rdx - scale); | 2656 | if (b->rdx > scale) bc_num_truncate(b, b->rdx - scale); |
