Skip to content

Commit 8a3f06c

Browse files
gh-81057: Move time Globals to _PyRuntimeState (gh-100122)
#81057
1 parent cda9f02 commit 8a3f06c

14 files changed

+100
-118
lines changed

Include/internal/pycore_os.h

-38
This file was deleted.

Include/internal/pycore_pylifecycle.h

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern void _PySys_Fini(PyInterpreterState *interp);
4444
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
4545
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
4646

47+
extern PyStatus _PyTime_Init(void);
4748
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
4849
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
4950
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);

Include/internal/pycore_runtime.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extern "C" {
2121
#include "pycore_pymem.h" // struct _pymem_allocators
2222
#include "pycore_pyhash.h" // struct pyhash_runtime_state
2323
#include "pycore_obmalloc.h" // struct obmalloc_state
24-
#include "pycore_os.h" // struct _os_runtime_state
24+
#include "pycore_time.h" // struct _time_runtime_state
2525
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
2626

2727
struct _getargs_runtime_state {
@@ -104,7 +104,7 @@ typedef struct pyruntimestate {
104104
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
105105
int unhandled_keyboard_interrupt;
106106
} signals;
107-
struct _os_runtime_state os;
107+
struct _time_runtime_state time;
108108

109109
struct pyinterpreters {
110110
PyThread_type_lock mutex;

Include/internal/pycore_runtime_init.h

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ extern "C" {
2626
}, \
2727
.obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \
2828
.pyhash_state = pyhash_state_INIT, \
29-
.os = _OS_RUNTIME_INIT, \
3029
.interpreters = { \
3130
/* This prevents interpreters from getting created \
3231
until _PyInterpreterState_Enable() is called. */ \

Include/internal/pycore_time.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef Py_INTERNAL_TIME_H
2+
#define Py_INTERNAL_TIME_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
12+
struct _time_runtime_state {
13+
#ifdef HAVE_TIMES
14+
int ticks_per_second_initialized;
15+
long ticks_per_second;
16+
#else
17+
int _not_used;
18+
#endif
19+
};
20+
21+
22+
#ifdef __cplusplus
23+
}
24+
#endif
25+
#endif /* !Py_INTERNAL_TIME_H */

Makefile.pre.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,6 @@ PYTHON_HEADERS= \
16541654
$(srcdir)/Include/internal/pycore_object.h \
16551655
$(srcdir)/Include/internal/pycore_obmalloc.h \
16561656
$(srcdir)/Include/internal/pycore_obmalloc_init.h \
1657-
$(srcdir)/Include/internal/pycore_os.h \
16581657
$(srcdir)/Include/internal/pycore_pathconfig.h \
16591658
$(srcdir)/Include/internal/pycore_pyarena.h \
16601659
$(srcdir)/Include/internal/pycore_pyerrors.h \
@@ -1673,6 +1672,7 @@ PYTHON_HEADERS= \
16731672
$(srcdir)/Include/internal/pycore_structseq.h \
16741673
$(srcdir)/Include/internal/pycore_symtable.h \
16751674
$(srcdir)/Include/internal/pycore_sysmodule.h \
1675+
$(srcdir)/Include/internal/pycore_time.h \
16761676
$(srcdir)/Include/internal/pycore_token.h \
16771677
$(srcdir)/Include/internal/pycore_traceback.h \
16781678
$(srcdir)/Include/internal/pycore_tuple.h \

Modules/posixmodule.c

+5-25
Original file line numberDiff line numberDiff line change
@@ -9065,24 +9065,6 @@ build_times_result(PyObject *module, double user, double system,
90659065
}
90669066

90679067

9068-
#ifdef _OS_NEED_TICKS_PER_SECOND
9069-
#define ticks_per_second _PyRuntime.os.ticks_per_second
9070-
static void
9071-
ticks_per_second_init(void)
9072-
{
9073-
if (ticks_per_second != -1) {
9074-
return;
9075-
}
9076-
# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9077-
ticks_per_second = sysconf(_SC_CLK_TCK);
9078-
# elif defined(HZ)
9079-
ticks_per_second = HZ;
9080-
# else
9081-
ticks_per_second = 60; /* magic fallback value; may be bogus */
9082-
# endif
9083-
}
9084-
#endif
9085-
90869068
/*[clinic input]
90879069
os.times
90889070
@@ -9116,22 +9098,24 @@ os_times_impl(PyObject *module)
91169098
(double)0,
91179099
(double)0);
91189100
}
9119-
#elif !defined(_OS_NEED_TICKS_PER_SECOND)
9120-
# error "missing ticks_per_second"
91219101
#else /* MS_WINDOWS */
91229102
{
91239103
struct tms t;
91249104
clock_t c;
91259105
errno = 0;
91269106
c = times(&t);
9127-
if (c == (clock_t) -1)
9107+
if (c == (clock_t) -1) {
91289108
return posix_error();
9109+
}
9110+
assert(_PyRuntime.time.ticks_per_second_initialized);
9111+
#define ticks_per_second _PyRuntime.time.ticks_per_second
91299112
return build_times_result(module,
91309113
(double)t.tms_utime / ticks_per_second,
91319114
(double)t.tms_stime / ticks_per_second,
91329115
(double)t.tms_cutime / ticks_per_second,
91339116
(double)t.tms_cstime / ticks_per_second,
91349117
(double)c / ticks_per_second);
9118+
#undef ticks_per_second
91359119
}
91369120
#endif /* MS_WINDOWS */
91379121
#endif /* HAVE_TIMES */
@@ -15950,10 +15934,6 @@ posixmodule_exec(PyObject *m)
1595015934
PyModule_AddObject(m, "statvfs_result", Py_NewRef(StatVFSResultType));
1595115935
state->StatVFSResultType = StatVFSResultType;
1595215936

15953-
#ifdef _OS_NEED_TICKS_PER_SECOND
15954-
ticks_per_second_init();
15955-
#endif
15956-
1595715937
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
1595815938
sched_param_desc.name = MODNAME ".sched_param";
1595915939
PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);

Modules/timemodule.c

+53-41
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,54 @@
6262
#define SEC_TO_NS (1000 * 1000 * 1000)
6363

6464

65+
#ifdef HAVE_TIMES
66+
67+
static int
68+
check_ticks_per_second(long tps, const char *context)
69+
{
70+
/* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
71+
cannot overflow. */
72+
if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) {
73+
PyErr_Format(PyExc_OverflowError, "%s is too large", context);
74+
return -1;
75+
}
76+
return 0;
77+
}
78+
79+
# define ticks_per_second _PyRuntime.time.ticks_per_second
80+
81+
static void
82+
ensure_ticks_per_second(void)
83+
{
84+
if (_PyRuntime.time.ticks_per_second_initialized) {
85+
return;
86+
}
87+
_PyRuntime.time.ticks_per_second_initialized = 1;
88+
# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
89+
ticks_per_second = sysconf(_SC_CLK_TCK);
90+
if (ticks_per_second < 1) {
91+
ticks_per_second = -1;
92+
}
93+
# elif defined(HZ)
94+
ticks_per_second = HZ;
95+
# else
96+
ticks_per_second = 60; /* magic fallback value; may be bogus */
97+
# endif
98+
}
99+
100+
#endif /* HAVE_TIMES */
101+
102+
103+
PyStatus
104+
_PyTime_Init(void)
105+
{
106+
#ifdef HAVE_TIMES
107+
ensure_ticks_per_second();
108+
#endif
109+
return PyStatus_Ok();
110+
}
111+
112+
65113
/* Forward declarations */
66114
static int pysleep(_PyTime_t timeout);
67115

@@ -140,18 +188,8 @@ Return the current time in nanoseconds since the Epoch.");
140188
static int
141189
_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
142190
{
143-
static int initialized = 0;
144-
145-
if (!initialized) {
146-
initialized = 1;
147-
148-
/* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC)
149-
above cannot overflow */
150-
if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) {
151-
PyErr_SetString(PyExc_OverflowError,
152-
"CLOCKS_PER_SEC is too large");
153-
return -1;
154-
}
191+
if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) {
192+
return -1;
155193
}
156194

157195
if (info) {
@@ -1308,36 +1346,10 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
13081346
struct tms t;
13091347

13101348
if (times(&t) != (clock_t)-1) {
1311-
static long ticks_per_second = -1;
1312-
1313-
if (ticks_per_second == -1) {
1314-
long freq;
1315-
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
1316-
freq = sysconf(_SC_CLK_TCK);
1317-
if (freq < 1) {
1318-
freq = -1;
1319-
}
1320-
#elif defined(HZ)
1321-
freq = HZ;
1322-
#else
1323-
freq = 60; /* magic fallback value; may be bogus */
1324-
#endif
1325-
1326-
if (freq != -1) {
1327-
/* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second)
1328-
cannot overflow below */
1329-
#if LONG_MAX > _PyTime_MAX / SEC_TO_NS
1330-
if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) {
1331-
PyErr_SetString(PyExc_OverflowError,
1332-
"_SC_CLK_TCK is too large");
1333-
return -1;
1334-
}
1335-
#endif
1336-
1337-
ticks_per_second = freq;
1338-
}
1349+
assert(_PyRuntime.time.ticks_per_second_initialized);
1350+
if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) {
1351+
return -1;
13391352
}
1340-
13411353
if (ticks_per_second != -1) {
13421354
if (info) {
13431355
info->implementation = "times()";

PCbuild/_freeze_module.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
<ClCompile Include="..\Modules\getpath_noop.c" />
111111
<ClCompile Include="..\Modules\posixmodule.c" />
112112
<ClCompile Include="..\Modules\signalmodule.c" />
113+
<ClCompile Include="..\Modules\timemodule.c" />
113114
<ClCompile Include="..\Modules\_tracemalloc.c" />
114115
<ClCompile Include="..\Modules\_io\_iomodule.c" />
115116
<ClCompile Include="..\Modules\_io\bufferedio.c" />

PCbuild/_freeze_module.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@
367367
<ClCompile Include="..\Python\thread.c">
368368
<Filter>Source Files</Filter>
369369
</ClCompile>
370+
<ClCompile Include="..\Modules\timemodule.c">
371+
<Filter>Source Files</Filter>
372+
</ClCompile>
370373
<ClCompile Include="..\Parser\token.c">
371374
<Filter>Source Files</Filter>
372375
</ClCompile>

PCbuild/pythoncore.vcxproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@
236236
<ClInclude Include="..\Include\internal\pycore_object.h" />
237237
<ClInclude Include="..\Include\internal\pycore_obmalloc.h" />
238238
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h" />
239-
<ClInclude Include="..\Include\internal\pycore_os.h" />
240239
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
241240
<ClInclude Include="..\Include\internal\pycore_pyarena.h" />
242241
<ClInclude Include="..\Include\internal\pycore_pyerrors.h" />
@@ -255,6 +254,7 @@
255254
<ClInclude Include="..\Include\internal\pycore_structseq.h" />
256255
<ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
257256
<ClInclude Include="..\Include\internal\pycore_symtable.h" />
257+
<ClInclude Include="..\Include\internal\pycore_time.h" />
258258
<ClInclude Include="..\Include\internal\pycore_token.h" />
259259
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
260260
<ClInclude Include="..\Include\internal\pycore_tuple.h" />

PCbuild/pythoncore.vcxproj.filters

+3-3
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,6 @@
612612
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h">
613613
<Filter>Include\internal</Filter>
614614
</ClInclude>
615-
<ClInclude Include="..\Include\internal\pycore_os.h">
616-
<Filter>Include\internal</Filter>
617-
</ClInclude>
618615
<ClInclude Include="..\Include\internal\pycore_pathconfig.h">
619616
<Filter>Include\internal</Filter>
620617
</ClInclude>
@@ -666,6 +663,9 @@
666663
<ClInclude Include="..\Include\internal\pycore_symtable.h">
667664
<Filter>Include\internal</Filter>
668665
</ClInclude>
666+
<ClInclude Include="..\Include\internal\pycore_time.h">
667+
<Filter>Include\internal</Filter>
668+
</ClInclude>
669669
<ClInclude Include="..\Include\internal\pycore_token.h">
670670
<Filter>Include\internal</Filter>
671671
</ClInclude>

Python/pylifecycle.c

+5
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,11 @@ pycore_init_runtime(_PyRuntimeState *runtime,
606606
return status;
607607
}
608608

609+
status = _PyTime_Init();
610+
if (_PyStatus_EXCEPTION(status)) {
611+
return status;
612+
}
613+
609614
status = _PyImport_Init();
610615
if (_PyStatus_EXCEPTION(status)) {
611616
return status;

Tools/c-analyzer/cpython/globals-to-fix.tsv

-6
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,6 @@ Modules/faulthandler.c - old_stack -
387387
##################################
388388
## global non-objects to fix in builtin modules
389389

390-
##-----------------------
391-
## initialized once
392-
393-
Modules/timemodule.c _PyTime_GetClockWithInfo initialized -
394-
Modules/timemodule.c _PyTime_GetProcessTimeWithInfo ticks_per_second -
395-
396390
##-----------------------
397391
## state
398392

0 commit comments

Comments
 (0)