[Python-checkins] r75644 - in sandbox/trunk/newgil: Makefile.pre.in Python/ceval.c Python/ceval_gil.h Python/ceval_pthread.h

antoine.pitrou python-checkins at python.org
Sat Oct 24 00:57:42 CEST 2009


Author: antoine.pitrou
Date: Sat Oct 24 00:57:41 2009
New Revision: 75644

Log:
Rename file, since it is no longer posix-specific.



Added:
   sandbox/trunk/newgil/Python/ceval_gil.h
      - copied, changed from r75643, /sandbox/trunk/newgil/Python/ceval_pthread.h
Removed:
   sandbox/trunk/newgil/Python/ceval_pthread.h
Modified:
   sandbox/trunk/newgil/Makefile.pre.in
   sandbox/trunk/newgil/Python/ceval.c

Modified: sandbox/trunk/newgil/Makefile.pre.in
==============================================================================
--- sandbox/trunk/newgil/Makefile.pre.in	(original)
+++ sandbox/trunk/newgil/Makefile.pre.in	Sat Oct 24 00:57:41 2009
@@ -596,7 +596,7 @@
 $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES)
 	$(OPCODETARGETGEN) $(OPCODETARGETS_H)
 
-Python/ceval.o: $(OPCODETARGETS_H) Python/ceval_pthread.h
+Python/ceval.o: $(OPCODETARGETS_H) Python/ceval_gil.h
 
 Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \
 				$(BYTESTR_DEPS) \

Modified: sandbox/trunk/newgil/Python/ceval.c
==============================================================================
--- sandbox/trunk/newgil/Python/ceval.c	(original)
+++ sandbox/trunk/newgil/Python/ceval.c	Sat Oct 24 00:57:41 2009
@@ -239,7 +239,7 @@
 /* Request for looking at the `async_exc` field of the current thread state */
 static volatile int pending_async_exc = 0;
 
-#include "ceval_pthread.h"
+#include "ceval_gil.h"
 
 int
 PyEval_ThreadsInitialized(void)

Copied: sandbox/trunk/newgil/Python/ceval_gil.h (from r75643, /sandbox/trunk/newgil/Python/ceval_pthread.h)
==============================================================================
--- /sandbox/trunk/newgil/Python/ceval_pthread.h	(original)
+++ sandbox/trunk/newgil/Python/ceval_gil.h	Sat Oct 24 00:57:41 2009
@@ -1,5 +1,5 @@
 /*
- * Implementation of the Global Interpreter Lock (GIL) for POSIX pthreads.
+ * Implementation of the Global Interpreter Lock (GIL).
  */
 
 #include <stdlib.h>

Deleted: sandbox/trunk/newgil/Python/ceval_pthread.h
==============================================================================
--- sandbox/trunk/newgil/Python/ceval_pthread.h	Sat Oct 24 00:57:41 2009
+++ (empty file)
@@ -1,358 +0,0 @@
-/*
- * Implementation of the Global Interpreter Lock (GIL) for POSIX pthreads.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-
-
-/* First some general settings */
-
-/* milliseconds */
-#define INTERVAL 5
-
-/* Enable if you want to force the switching of threads at least every INTERVAL */
-#undef FORCE_SWITCHING
-#define FORCE_SWITCHING
-
-#undef TRACE_PRIO
-/* #define TRACE_PRIO */
-
-
-#ifndef _POSIX_THREADS
-/* This means pthreads are not implemented in libc headers, hence the macro
-   not present in unistd.h. But they still can be implemented as an external
-   library (e.g. gnu pth in pthread emulation) */
-# ifdef HAVE_PTHREAD_H
-#  include <pthread.h> /* _POSIX_THREADS */
-# endif
-#endif
-
-
-#ifdef _POSIX_THREADS
-
-/*
- * POSIX support
- */
-
-#include <pthread.h>
-
-#define ADD_MILLISECONDS(tv, interval) \
-do { \
-    tv.tv_usec += interval * 1000; \
-    tv.tv_sec += tv.tv_usec / 1000000; \
-    tv.tv_usec %= 1000000; \
-} while (0)
-
-/* We assume all modern POSIX systems have gettimeofday() */
-#ifdef GETTIMEOFDAY_NO_TZ
-#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
-#else
-#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
-#endif
-
-#define MUTEX_T pthread_mutex_t
-#define MUTEX_INIT(mut) \
-    if (pthread_mutex_init(&mut, NULL)) { \
-        Py_FatalError("pthread_mutex_init(" #mut ") failed"); };
-#define MUTEX_LOCK(mut) \
-    if (pthread_mutex_lock(&mut)) { \
-        Py_FatalError("pthread_mutex_lock(" #mut ") failed"); };
-#define MUTEX_UNLOCK(mut) \
-    if (pthread_mutex_unlock(&mut)) { \
-        Py_FatalError("pthread_mutex_unlock(" #mut ") failed"); };
-
-#define COND_T pthread_cond_t
-#define COND_INIT(cond) \
-    if (pthread_cond_init(&cond, NULL)) { \
-        Py_FatalError("pthread_cond_init(" #cond ") failed"); };
-#define COND_PREPARE(cond)
-#define COND_SIGNAL(cond) \
-    if (pthread_cond_signal(&cond)) { \
-        Py_FatalError("pthread_cond_signal(" #cond ") failed"); };
-#define COND_WAIT(cond, mut) \
-    if (pthread_cond_wait(&cond, &mut)) { \
-        Py_FatalError("pthread_cond_wait(" #cond ") failed"); };
-#define COND_TIMED_WAIT(cond, mut, milliseconds, timeout_result) \
-    { \
-        int r; \
-        struct timespec ts; \
-        struct timeval deadline; \
-        \
-        GETTIMEOFDAY(&deadline); \
-        ADD_MILLISECONDS(deadline, INTERVAL); \
-        ts.tv_sec = deadline.tv_sec; \
-        ts.tv_nsec = deadline.tv_usec * 1000; \
-        \
-        r = pthread_cond_timedwait(&cond, &mut, &ts); \
-        if (r == ETIMEDOUT) \
-            timeout_result = 1; \
-        else if (r) \
-            Py_FatalError("pthread_cond_timedwait(" #cond ") failed"); \
-        else \
-            timeout_result = 0; \
-    } \
-
-#elif defined(NT_THREADS)
-
-/*
- * Windows (2000 and later, as well as (hopefully) CE) support
- */
-
-#include <windows.h>
-
-#define MUTEX_T HANDLE
-#define MUTEX_INIT(mut) \
-    if (!(mut = CreateMutex(NULL, FALSE, NULL))) { \
-        Py_FatalError("CreateMutex(" #mut ") failed"); };
-#define MUTEX_LOCK(mut) \
-    if (WaitForSingleObject(mut, INFINITE) != WAIT_OBJECT_0) { \
-        Py_FatalError("WaitForSingleObject(" #mut ") failed"); };
-#define MUTEX_UNLOCK(mut) \
-    if (!ReleaseMutex(mut)) { \
-        Py_FatalError("ReleaseMutex(" #mut ") failed"); };
-
-/* We emulate condition variables with events. It is sufficient here.
-   (WaitForMultipleObjects() allows the event to be reset and the mutex
-   to be taken atomically) */
-#define COND_T HANDLE
-#define COND_INIT(cond) \
-    /* auto-reset, non-signalled */ \
-    if (!(cond = CreateEvent(NULL, FALSE, FALSE, NULL))) { \
-        Py_FatalError("CreateMutex(" #cond ") failed"); };
-#define COND_PREPARE(cond) \
-    if (!ResetEvent(cond)) { \
-        Py_FatalError("ResetEvent(" #cond ") failed"); };
-#define COND_SIGNAL(cond) \
-    if (!SetEvent(cond)) { \
-        Py_FatalError("SetEvent(" #cond ") failed"); };
-#define COND_WAIT(cond, mut) \
-    { \
-        DWORD r; \
-        HANDLE objects[2] = { cond, mut }; \
-        MUTEX_UNLOCK(mut); \
-        r = WaitForMultipleObjects(2, objects, TRUE, INFINITE); \
-        if (r != WAIT_OBJECT_0) \
-            Py_FatalError("WaitForSingleObject(" #cond ") failed"); \
-    }
-#define COND_TIMED_WAIT(cond, mut, milliseconds, timeout_result) \
-    { \
-        DWORD r; \
-        HANDLE objects[2] = { cond, mut }; \
-        MUTEX_UNLOCK(mut); \
-        r = WaitForMultipleObjects(2, objects, TRUE, milliseconds); \
-        if (r == WAIT_TIMEOUT) { \
-            MUTEX_LOCK(mut); \
-            timeout_result = 1; \
-        } \
-        else if (r != WAIT_OBJECT_0) \
-            Py_FatalError("WaitForSingleObject(" #cond ") failed"); \
-        else \
-            timeout_result = 0; \
-    }
-
-#else
-
-#error You need either a POSIX-compatible or a Windows system!
-
-#endif /* _POSIX_THREADS, NT_THREADS */
-
-
-/* Whether the GIL is already taken (-1 if uninitialized) */
-static volatile int gil_locked = -1;
-/* Number of GIL switches since the beginning */
-static unsigned long gil_switch_number = 0;
-/* Last thread holding / having held the GIL */
-static PyThreadState *gil_last_holder = NULL;
-
-/* This condition variable allows to put threads to sleep.
-   In addition, the mutex also protects the above variables. */
-static COND_T gil_cond;
-static MUTEX_T gil_mutex;
-/* This mutex is taken when a priority request is made, and released when
-   it is finally honoured.
-   Other threads can sleep by trying to lock the mutex. */
-static MUTEX_T prio_mutex;
-/* The thread making the prio request, or NULL. */
-static volatile PyThreadState *prio_request = NULL;
-
-#ifdef FORCE_SWITCHING
-/* This condition variable forces the GIL-releasing thread to wait for
-   the scheduling of a GIL-awaiting thread, if any. */
-static COND_T switch_cond;
-static MUTEX_T switch_mutex;
-#endif
-
-
-#define YIELD_IF_PRIO_REQUEST() \
-do { \
-    if (prio_request) { \
-        MUTEX_LOCK(prio_mutex); \
-        MUTEX_UNLOCK(prio_mutex); \
-    } \
-} while (0)
-
-
-
-static int gil_created(void)
-{
-    return gil_locked >= 0;
-}
-
-static void create_gil(void)
-{
-    MUTEX_INIT(gil_mutex);
-    MUTEX_INIT(prio_mutex);
-#ifdef FORCE_SWITCHING
-    MUTEX_INIT(switch_mutex);
-#endif
-    COND_INIT(gil_cond);
-#ifdef FORCE_SWITCHING
-    COND_INIT(switch_cond);
-#endif
-    gil_locked = 0;
-    gil_last_holder = NULL;
-    prio_request = NULL;
-}
-
-static void recreate_gil(void)
-{
-    create_gil();
-}
-
-static void drop_gil(PyThreadState *tstate)
-{
-    /* NOTE: tstate is allowed to be NULL. */
-    if (!gil_locked)
-        Py_FatalError("drop_gil: GIL is not locked");
-    if (tstate != NULL && tstate != gil_last_holder)
-        Py_FatalError("drop_gil: wrong thread state");
-
-    MUTEX_LOCK(gil_mutex);
-    gil_locked = 0;
-    COND_SIGNAL(gil_cond);
-#ifdef FORCE_SWITCHING
-    COND_PREPARE(switch_cond);
-#endif
-    MUTEX_UNLOCK(gil_mutex);
-    
-#ifdef FORCE_SWITCHING
-    if (gil_drop_request) {
-        MUTEX_LOCK(switch_mutex);
-        /* Not switched yet => wait */
-        if (gil_last_holder == tstate)
-            COND_WAIT(switch_cond, switch_mutex);
-        MUTEX_UNLOCK(switch_mutex);
-    }
-#endif
-}
-
-static void _take_gil(PyThreadState *tstate, int prio)
-{
-    int err;
-    if (tstate == NULL)
-        Py_FatalError("take_gil: NULL tstate");
-
-    /* If another thread is requesting priority, give it a chance to run
-       before we take the mutex.
-    */
-    YIELD_IF_PRIO_REQUEST();
-
-    err = errno;
-    MUTEX_LOCK(gil_mutex);
-
-    if (!gil_locked) {
-        prio = 0;
-        goto _ready;
-    }
-    
-    COND_PREPARE(gil_cond);
-    
-    if (prio) {
-#ifdef TRACE_PRIO
-        struct timeval tv;
-        GETTIMEOFDAY(&tv);
-        printf("trying to take gil with prio: %.3f <--\n",
-                   tv.tv_sec + tv.tv_usec / 1000000.0);
-#endif
-        if (!prio_request) {
-            MUTEX_LOCK(prio_mutex);
-            prio_request = tstate;
-        }
-        else
-            prio = 0;
-    }
-    while (gil_locked) {
-        int timed_out = 0;
-        unsigned long saved_switchnum;
-
-        if (prio_request) {
-            /* Tell the eval loop the GIL must be dropped as soon as possible */
-            SET_GIL_DROP_REQUEST();
-            if (!prio) {
-                /* If another thread is making the prio_request, give it a
-                   chance to run and take the mutex. */
-                MUTEX_UNLOCK(gil_mutex);
-                YIELD_IF_PRIO_REQUEST();
-                MUTEX_LOCK(gil_mutex);
-            }
-        }
-
-        saved_switchnum = gil_switch_number;
-        COND_TIMED_WAIT(gil_cond, gil_mutex, INTERVAL, timed_out);
-        /* If we timed out and no switch occurred in the meantime, it is time
-           to ask the GIL-holding thread to drop it. */
-        if (timed_out && gil_locked && gil_switch_number == saved_switchnum) {
-            SET_GIL_DROP_REQUEST();
-        }
-    }
-_ready:
-#ifdef FORCE_SWITCHING
-    /* This mutex must be taken before modifying gil_last_holder (see drop_gil()). */
-    MUTEX_LOCK(switch_mutex);
-#endif
-    /* We now hold the GIL */
-    gil_locked = 1;
-
-    if (tstate != gil_last_holder) {
-        gil_last_holder = tstate;
-        ++gil_switch_number;
-#ifdef TRACE_PRIO
-        if (prio) {
-            struct timeval tv;
-            GETTIMEOFDAY(&tv);
-            printf("gil taken with prio:          %.3f\n",
-                   tv.tv_sec + tv.tv_usec / 1000000.0);
-        }
-#endif
-    }
-#ifdef FORCE_SWITCHING
-    COND_SIGNAL(switch_cond);
-    MUTEX_UNLOCK(switch_mutex);
-#endif
-    if (prio) {
-        /* The prio request was granted. */
-        prio_request = NULL;
-        MUTEX_UNLOCK(prio_mutex);
-    }
-    if (gil_drop_request && !prio_request) {
-        /* No prio_request pending. */
-        RESET_GIL_DROP_REQUEST();
-    }
-    if (tstate->async_exc != NULL) {
-        _PyEval_SignalAsyncExc();
-    }
-    
-    MUTEX_UNLOCK(gil_mutex);
-    errno = err;
-}
-
-static void take_gil(PyThreadState *tstate)
-{
-    _take_gil(tstate, 0);
-}
-
-static void take_gil_prio(PyThreadState *tstate)
-{
-    _take_gil(tstate, 1);
-}


More information about the Python-checkins mailing list