Skip to content

long_from_non_binary_base isn't thread-safe with free threading #130599

Closed
@colesbury

Description

@colesbury

Bug report

The long_from_non_binary_base function in longobject.c isn't thread-safe with free threading or per-interpreter GIL due to the initialization of log_base_BASE, convwidth_base, and convmultmax_base:

cpython/Objects/longobject.c

Lines 2835 to 2856 in f963239

static double log_base_BASE[37] = {0.0e0,};
static int convwidth_base[37] = {0,};
static twodigits convmultmax_base[37] = {0,};
if (log_base_BASE[base] == 0.0) {
twodigits convmax = base;
int i = 1;
log_base_BASE[base] = (log((double)base) /
log((double)PyLong_BASE));
for (;;) {
twodigits next = convmax * base;
if (next > PyLong_BASE) {
break;
}
convmax = next;
++i;
}
convmultmax_base[base] = convmax;
assert(i > 0);
convwidth_base[base] = i;
}

There are a few ways we could make this thread-safe:

  • Make the initialization thread-safe with something like _PyOnceFlag
  • Pre-compute the values and hardcode them.

Originally reported by @ngoldbaum in #130421

cc @tim-one

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions