bpo-36301: Add _PyRuntime.pre_initialized (GH-12457)

* Add _PyRuntime.pre_initialized: set to 1 when Python
  is pre-initialized
* Add _Py_PreInitialize() and _Py_PreInitializeFromPreConfig().
* _PyCoreConfig_Read() now calls  _Py_PreInitialize().
* Move _PyPreConfig_GetGlobalConfig() and
  _PyCoreConfig_GetGlobalConfig() calls from main.c to preconfig.c
  and coreconfig.c.
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index 3bffc80..1caeb98 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -14,6 +14,10 @@
 
 /* PEP 432 Multi-phase initialization API (Private while provisional!) */
 
+PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void);
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig(
+    _PyPreConfig *preconfig);
+
 PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
     PyInterpreterState **interp,
     const _PyCoreConfig *);
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 7c9d11a..911e7ee 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -134,8 +134,15 @@
 /* Full Python runtime state */
 
 typedef struct pyruntimestate {
-    int initialized;
+    /* Is Python pre-initialized? Set to 1 by _Py_PreInitialize() */
+    int pre_initialized;
+
+    /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
     int core_initialized;
+
+    /* Is Python fully initialized? Set to 1 by Py_Initialize() */
+    int initialized;
+
     PyThreadState *finalizing;
 
     struct pyinterpreters {
@@ -172,7 +179,8 @@
     // XXX Consolidate globals found via the check-c-globals script.
 } _PyRuntimeState;
 
-#define _PyRuntimeState_INIT {.initialized = 0, .core_initialized = 0}
+#define _PyRuntimeState_INIT \
+    {.pre_initialized = 0, .core_initialized = 0, .initialized = 0}
 /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
 
 PyAPI_DATA(_PyRuntimeState) _PyRuntime;