LCOV - code coverage report
Current view: top level - Python - thread.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 46 56 82.1 %
Date: 2022-07-07 18:19:46 Functions: 8 8 100.0 %

          Line data    Source code
       1             : 
       2             : /* Thread package.
       3             :    This is intended to be usable independently from Python.
       4             :    The implementation for system foobar is in a file thread_foobar.h
       5             :    which is included by this file dependent on config settings.
       6             :    Stuff shared by all thread_*.h files is collected here. */
       7             : 
       8             : #include "Python.h"
       9             : #include "pycore_pystate.h"       // _PyInterpreterState_GET()
      10             : #include "pycore_structseq.h"     // _PyStructSequence_FiniType()
      11             : 
      12             : #ifndef _POSIX_THREADS
      13             : /* This means pthreads are not implemented in libc headers, hence the macro
      14             :    not present in unistd.h. But they still can be implemented as an external
      15             :    library (e.g. gnu pth in pthread emulation) */
      16             : # ifdef HAVE_PTHREAD_H
      17             : #  include <pthread.h> /* _POSIX_THREADS */
      18             : # endif
      19             : #endif
      20             : 
      21             : #ifndef DONT_HAVE_STDIO_H
      22             : #include <stdio.h>
      23             : #endif
      24             : 
      25             : #include <stdlib.h>
      26             : 
      27             : #ifndef _POSIX_THREADS
      28             : 
      29             : /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
      30             :    enough of the Posix threads package is implemented to support python
      31             :    threads.
      32             : 
      33             :    This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
      34             :    a check of __ia64 to verify that we're running on an ia64 system instead
      35             :    of a pa-risc system.
      36             : */
      37             : #ifdef __hpux
      38             : #ifdef _SC_THREADS
      39             : #define _POSIX_THREADS
      40             : #endif
      41             : #endif
      42             : 
      43             : #endif /* _POSIX_THREADS */
      44             : 
      45             : static int initialized;
      46             : 
      47             : static void PyThread__init_thread(void); /* Forward */
      48             : 
      49             : void
      50        9043 : PyThread_init_thread(void)
      51             : {
      52        9043 :     if (initialized)
      53        6093 :         return;
      54        2950 :     initialized = 1;
      55        2950 :     PyThread__init_thread();
      56             : }
      57             : 
      58             : #if defined(_POSIX_THREADS)
      59             : #   define PYTHREAD_NAME "pthread"
      60             : #   include "thread_pthread.h"
      61             : #elif defined(NT_THREADS)
      62             : #   define PYTHREAD_NAME "nt"
      63             : #   include "thread_nt.h"
      64             : #else
      65             : #   error "Require native threads. See https://bugs.python.org/issue31370"
      66             : #endif
      67             : 
      68             : 
      69             : /* return the current thread stack size */
      70             : size_t
      71          15 : PyThread_get_stacksize(void)
      72             : {
      73          15 :     return _PyInterpreterState_GET()->threads.stacksize;
      74             : }
      75             : 
      76             : /* Only platforms defining a THREAD_SET_STACKSIZE() macro
      77             :    in thread_<platform>.h support changing the stack size.
      78             :    Return 0 if stack size is valid,
      79             :       -1 if stack size value is invalid,
      80             :       -2 if setting stack size is not supported. */
      81             : int
      82          15 : PyThread_set_stacksize(size_t size)
      83             : {
      84             : #if defined(THREAD_SET_STACKSIZE)
      85          15 :     return THREAD_SET_STACKSIZE(size);
      86             : #else
      87             :     return -2;
      88             : #endif
      89             : }
      90             : 
      91             : 
      92             : /* Thread Specific Storage (TSS) API
      93             : 
      94             :    Cross-platform components of TSS API implementation.
      95             : */
      96             : 
      97             : Py_tss_t *
      98           1 : PyThread_tss_alloc(void)
      99             : {
     100           1 :     Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t));
     101           1 :     if (new_key == NULL) {
     102           0 :         return NULL;
     103             :     }
     104           1 :     new_key->_is_initialized = 0;
     105           1 :     return new_key;
     106             : }
     107             : 
     108             : void
     109           1 : PyThread_tss_free(Py_tss_t *key)
     110             : {
     111           1 :     if (key != NULL) {
     112           1 :         PyThread_tss_delete(key);
     113           1 :         PyMem_RawFree((void *)key);
     114             :     }
     115           1 : }
     116             : 
     117             : int
     118  3026140000 : PyThread_tss_is_created(Py_tss_t *key)
     119             : {
     120  3026140000 :     assert(key != NULL);
     121  3026140000 :     return key->_is_initialized;
     122             : }
     123             : 
     124             : 
     125             : PyDoc_STRVAR(threadinfo__doc__,
     126             : "sys.thread_info\n\
     127             : \n\
     128             : A named tuple holding information about the thread implementation.");
     129             : 
     130             : static PyStructSequence_Field threadinfo_fields[] = {
     131             :     {"name",    "name of the thread implementation"},
     132             :     {"lock",    "name of the lock implementation"},
     133             :     {"version", "name and version of the thread library"},
     134             :     {0}
     135             : };
     136             : 
     137             : static PyStructSequence_Desc threadinfo_desc = {
     138             :     "sys.thread_info",           /* name */
     139             :     threadinfo__doc__,           /* doc */
     140             :     threadinfo_fields,           /* fields */
     141             :     3
     142             : };
     143             : 
     144             : static PyTypeObject ThreadInfoType;
     145             : 
     146             : PyObject*
     147        3134 : PyThread_GetInfo(void)
     148             : {
     149             :     PyObject *threadinfo, *value;
     150        3134 :     int pos = 0;
     151             : #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
     152             :      && defined(_CS_GNU_LIBPTHREAD_VERSION))
     153             :     char buffer[255];
     154             :     int len;
     155             : #endif
     156             : 
     157        3134 :     if (ThreadInfoType.tp_name == 0) {
     158        2963 :         if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0)
     159           0 :             return NULL;
     160             :     }
     161             : 
     162        3134 :     threadinfo = PyStructSequence_New(&ThreadInfoType);
     163        3134 :     if (threadinfo == NULL)
     164           0 :         return NULL;
     165             : 
     166        3134 :     value = PyUnicode_FromString(PYTHREAD_NAME);
     167        3134 :     if (value == NULL) {
     168           0 :         Py_DECREF(threadinfo);
     169           0 :         return NULL;
     170             :     }
     171        3134 :     PyStructSequence_SET_ITEM(threadinfo, pos++, value);
     172             : 
     173             : #ifdef _POSIX_THREADS
     174             : #ifdef USE_SEMAPHORES
     175        3134 :     value = PyUnicode_FromString("semaphore");
     176             : #else
     177             :     value = PyUnicode_FromString("mutex+cond");
     178             : #endif
     179        3134 :     if (value == NULL) {
     180           0 :         Py_DECREF(threadinfo);
     181           0 :         return NULL;
     182             :     }
     183             : #else
     184             :     Py_INCREF(Py_None);
     185             :     value = Py_None;
     186             : #endif
     187        3134 :     PyStructSequence_SET_ITEM(threadinfo, pos++, value);
     188             : 
     189             : #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
     190             :      && defined(_CS_GNU_LIBPTHREAD_VERSION))
     191        3134 :     value = NULL;
     192        3134 :     len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
     193        3134 :     if (1 < len && (size_t)len < sizeof(buffer)) {
     194        3134 :         value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
     195        3134 :         if (value == NULL)
     196           0 :             PyErr_Clear();
     197             :     }
     198        3134 :     if (value == NULL)
     199             : #endif
     200             :     {
     201           0 :         Py_INCREF(Py_None);
     202           0 :         value = Py_None;
     203             :     }
     204        3134 :     PyStructSequence_SET_ITEM(threadinfo, pos++, value);
     205        3134 :     return threadinfo;
     206             : }
     207             : 
     208             : 
     209             : void
     210        3120 : _PyThread_FiniType(PyInterpreterState *interp)
     211             : {
     212        3120 :     if (!_Py_IsMainInterpreter(interp)) {
     213         169 :         return;
     214             :     }
     215             : 
     216        2951 :     _PyStructSequence_FiniType(&ThreadInfoType);
     217             : }

Generated by: LCOV version 1.14