* bignum.c: move object allocation out of blocking_region.
[ruby-dev:33139] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b9821b02a0
commit
67212c5ba4
@ -1,3 +1,8 @@
|
|||||||
|
Tue Jan 29 21:55:35 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
|
* bignum.c: move object allocation out of blocking_region.
|
||||||
|
[ruby-dev:33139]
|
||||||
|
|
||||||
Tue Jan 29 20:37:36 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Jan 29 20:37:36 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* enc/trans/make_transdb.rb: add for make transdb.h.
|
* enc/trans/make_transdb.rb: add for make transdb.h.
|
||||||
|
120
bignum.c
120
bignum.c
@ -1449,7 +1449,7 @@ rb_big_stop(void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct big_mul_struct {
|
struct big_mul_struct {
|
||||||
VALUE x, y, stop;
|
VALUE x, y, z, stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1458,11 +1458,10 @@ bigmul1(void *ptr)
|
|||||||
struct big_mul_struct *bms = (struct big_mul_struct*)ptr;
|
struct big_mul_struct *bms = (struct big_mul_struct*)ptr;
|
||||||
long i, j;
|
long i, j;
|
||||||
BDIGIT_DBL n = 0;
|
BDIGIT_DBL n = 0;
|
||||||
VALUE x = bms->x, y = bms->y, z;
|
VALUE x = bms->x, y = bms->y, z = bms->z;
|
||||||
BDIGIT *zds;
|
BDIGIT *zds;
|
||||||
|
|
||||||
j = RBIGNUM_LEN(x) + RBIGNUM_LEN(y) + 1;
|
j = RBIGNUM_LEN(x) + RBIGNUM_LEN(y) + 1;
|
||||||
z = bignew(j, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
|
|
||||||
zds = BDIGITS(z);
|
zds = BDIGITS(z);
|
||||||
while (j--) zds[j] = 0;
|
while (j--) zds[j] = 0;
|
||||||
for (i = 0; i < RBIGNUM_LEN(x); i++) {
|
for (i = 0; i < RBIGNUM_LEN(x); i++) {
|
||||||
@ -1488,7 +1487,7 @@ static VALUE
|
|||||||
rb_big_mul0(VALUE x, VALUE y)
|
rb_big_mul0(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
struct big_mul_struct bms;
|
struct big_mul_struct bms;
|
||||||
VALUE z;
|
volatile VALUE z;
|
||||||
|
|
||||||
switch (TYPE(y)) {
|
switch (TYPE(y)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
@ -1507,6 +1506,7 @@ rb_big_mul0(VALUE x, VALUE y)
|
|||||||
|
|
||||||
bms.x = x;
|
bms.x = x;
|
||||||
bms.y = y;
|
bms.y = y;
|
||||||
|
bms.z = bignew(RBIGNUM_LEN(x) + RBIGNUM_LEN(y) + 1, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
|
||||||
bms.stop = Qfalse;
|
bms.stop = Qfalse;
|
||||||
|
|
||||||
if (RBIGNUM_LEN(x) + RBIGNUM_LEN(y) > 10000) {
|
if (RBIGNUM_LEN(x) + RBIGNUM_LEN(y) > 10000) {
|
||||||
@ -1533,20 +1533,64 @@ rb_big_mul(VALUE x, VALUE y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct big_div_struct {
|
struct big_div_struct {
|
||||||
VALUE x, y, *divp, *modp, stop;
|
long nx, ny;
|
||||||
|
BDIGIT *yds, *zds;
|
||||||
|
VALUE stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
bigdivrem1(void *ptr)
|
bigdivrem1(void *ptr)
|
||||||
{
|
{
|
||||||
struct big_div_struct *bds = (struct big_div_struct*)ptr;
|
struct big_div_struct *bds = (struct big_div_struct*)ptr;
|
||||||
VALUE x = bds->x, y = bds->y, *divp = bds->divp, *modp = bds->modp;
|
long nx = bds->nx, ny = bds->ny;
|
||||||
long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
|
|
||||||
long i, j;
|
long i, j;
|
||||||
VALUE yy, z;
|
BDIGIT *yds = bds->yds, *zds = bds->zds;
|
||||||
BDIGIT *xds, *yds, *zds, *tds;
|
|
||||||
BDIGIT_DBL t2;
|
BDIGIT_DBL t2;
|
||||||
BDIGIT_DBL_SIGNED num;
|
BDIGIT_DBL_SIGNED num;
|
||||||
|
BDIGIT q;
|
||||||
|
|
||||||
|
j = nx==ny?nx+1:nx;
|
||||||
|
do {
|
||||||
|
if (bds->stop) return Qnil;
|
||||||
|
if (zds[j] == yds[ny-1]) q = BIGRAD-1;
|
||||||
|
else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
|
||||||
|
if (q) {
|
||||||
|
i = 0; num = 0; t2 = 0;
|
||||||
|
do { /* multiply and subtract */
|
||||||
|
BDIGIT_DBL ee;
|
||||||
|
t2 += (BDIGIT_DBL)yds[i] * q;
|
||||||
|
ee = num - BIGLO(t2);
|
||||||
|
num = (BDIGIT_DBL)zds[j - ny + i] + ee;
|
||||||
|
if (ee) zds[j - ny + i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
t2 = BIGDN(t2);
|
||||||
|
} while (++i < ny);
|
||||||
|
num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */
|
||||||
|
while (num) { /* "add back" required */
|
||||||
|
i = 0; num = 0; q--;
|
||||||
|
do {
|
||||||
|
BDIGIT_DBL ee = num + yds[i];
|
||||||
|
num = (BDIGIT_DBL)zds[j - ny + i] + ee;
|
||||||
|
if (ee) zds[j - ny + i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
|
} while (++i < ny);
|
||||||
|
num--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zds[j] = q;
|
||||||
|
} while (--j >= ny);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
bigdivrem(VALUE x, VALUE y, VALUE *divp, VALUE *modp)
|
||||||
|
{
|
||||||
|
struct big_div_struct bds;
|
||||||
|
long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
|
||||||
|
long i, j;
|
||||||
|
volatile VALUE yy, z;
|
||||||
|
BDIGIT *xds, *yds, *zds, *tds;
|
||||||
|
BDIGIT_DBL t2;
|
||||||
BDIGIT dd, q;
|
BDIGIT dd, q;
|
||||||
|
|
||||||
if (BIGZEROP(y)) rb_num_zerodiv();
|
if (BIGZEROP(y)) rb_num_zerodiv();
|
||||||
@ -1612,36 +1656,18 @@ bigdivrem1(void *ptr)
|
|||||||
while (j--) zds[j] = xds[j];
|
while (j--) zds[j] = xds[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
j = nx==ny?nx+1:nx;
|
bds.nx = nx;
|
||||||
do {
|
bds.ny = ny;
|
||||||
if (bds->stop) return Qnil;
|
bds.zds = zds;
|
||||||
if (zds[j] == yds[ny-1]) q = BIGRAD-1;
|
bds.yds = yds;
|
||||||
else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
|
bds.stop = Qfalse;
|
||||||
if (q) {
|
if (RBIGNUM_LEN(x) > 10000 || RBIGNUM_LEN(y) > 10000) {
|
||||||
i = 0; num = 0; t2 = 0;
|
rb_thread_blocking_region(bigdivrem1, &bds, rb_big_stop, &bds.stop);
|
||||||
do { /* multiply and subtract */
|
|
||||||
BDIGIT_DBL ee;
|
|
||||||
t2 += (BDIGIT_DBL)yds[i] * q;
|
|
||||||
ee = num - BIGLO(t2);
|
|
||||||
num = (BDIGIT_DBL)zds[j - ny + i] + ee;
|
|
||||||
if (ee) zds[j - ny + i] = BIGLO(num);
|
|
||||||
num = BIGDN(num);
|
|
||||||
t2 = BIGDN(t2);
|
|
||||||
} while (++i < ny);
|
|
||||||
num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */
|
|
||||||
while (num) { /* "add back" required */
|
|
||||||
i = 0; num = 0; q--;
|
|
||||||
do {
|
|
||||||
BDIGIT_DBL ee = num + yds[i];
|
|
||||||
num = (BDIGIT_DBL)zds[j - ny + i] + ee;
|
|
||||||
if (ee) zds[j - ny + i] = BIGLO(num);
|
|
||||||
num = BIGDN(num);
|
|
||||||
} while (++i < ny);
|
|
||||||
num--;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
bigdivrem1(&bds);
|
||||||
}
|
}
|
||||||
zds[j] = q;
|
|
||||||
} while (--j >= ny);
|
|
||||||
if (divp) { /* move quotient down in z */
|
if (divp) { /* move quotient down in z */
|
||||||
*divp = rb_big_clone(z);
|
*divp = rb_big_clone(z);
|
||||||
zds = BDIGITS(*divp);
|
zds = BDIGITS(*divp);
|
||||||
@ -1665,26 +1691,6 @@ bigdivrem1(void *ptr)
|
|||||||
RBIGNUM_SET_LEN(*modp, ny);
|
RBIGNUM_SET_LEN(*modp, ny);
|
||||||
RBIGNUM_SET_SIGN(*modp, RBIGNUM_SIGN(x));
|
RBIGNUM_SET_SIGN(*modp, RBIGNUM_SIGN(x));
|
||||||
}
|
}
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
bigdivrem(VALUE x, VALUE y, VALUE *divp, VALUE *modp)
|
|
||||||
{
|
|
||||||
struct big_div_struct bds;
|
|
||||||
VALUE z;
|
|
||||||
|
|
||||||
bds.x = x;
|
|
||||||
bds.y = y;
|
|
||||||
bds.divp = divp;
|
|
||||||
bds.modp = modp;
|
|
||||||
bds.stop = Qfalse;
|
|
||||||
if (RBIGNUM_LEN(x) > 10000 || RBIGNUM_LEN(y) > 10000) {
|
|
||||||
z = rb_thread_blocking_region(bigdivrem1, &bds, rb_big_stop, &bds.stop);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
z = bigdivrem1(&bds);
|
|
||||||
}
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user