Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
001fee14
Commit
001fee14
authored
Feb 20, 2019
by
Inada Naoki
Committed by
GitHub
Feb 20, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-12822: use monotonic clock for condvar if possible (GH-11723)
parent
46a97920
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
87 additions
and
51 deletions
+87
-51
Makefile.pre.in
Makefile.pre.in
+3
-2
Misc/NEWS.d/next/Core and Builtins/2019-02-05-12-48-23.bpo-12822.0x2NDx.rst
...ore and Builtins/2019-02-05-12-48-23.bpo-12822.0x2NDx.rst
+2
-0
Python/ceval.c
Python/ceval.c
+1
-0
Python/condvar.h
Python/condvar.h
+12
-28
Python/thread_pthread.h
Python/thread_pthread.h
+62
-19
configure
configure
+2
-1
configure.ac
configure.ac
+2
-1
pyconfig.h.in
pyconfig.h.in
+3
-0
No files found.
Makefile.pre.in
View file @
001fee14
...
...
@@ -939,7 +939,8 @@ regen-opcode-targets:
$(srcdir)
/Python/opcode_targets.h.new
$(UPDATE_FILE)
$(srcdir)
/Python/opcode_targets.h
$(srcdir)
/Python/opcode_targets.h.new
Python/ceval.o
:
$(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h
Python/ceval.o
:
$(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h
\
$(srcdir)/Python/condvar.h
Python/frozen.o
:
$(srcdir)/Python/importlib.h $(srcdir)/Python/importlib_external.h
\
$(srcdir)/Python/importlib_zipimport.h
...
...
@@ -1838,7 +1839,7 @@ patchcheck: @DEF_MAKE_RULE@
# Dependencies
Python/thread.o
:
@THREADHEADERS@
Python/thread.o
:
@THREADHEADERS@
$(srcdir)/Python/condvar.h
# Declare targets that aren't real files
.PHONY
:
all build_all sharedmods check-clean-src oldsharedmods test quicktest
...
...
Misc/NEWS.d/next/Core and Builtins/2019-02-05-12-48-23.bpo-12822.0x2NDx.rst
0 → 100644
View file @
001fee14
Use monotonic clock for ``pthread_cond_timedwait`` when
``pthread_condattr_setclock`` and ``CLOCK_MONOTONIC`` are available.
Python/ceval.c
View file @
001fee14
...
...
@@ -171,6 +171,7 @@ PyEval_InitThreads(void)
{
if
(
gil_created
())
return
;
PyThread_init_thread
();
create_gil
();
take_gil
(
_PyThreadState_GET
());
_PyRuntime
.
ceval
.
pending
.
main_thread
=
PyThread_get_thread_ident
();
...
...
Python/condvar.h
View file @
001fee14
...
...
@@ -48,19 +48,9 @@
* POSIX support
*/
#define PyCOND_ADD_MICROSECONDS(tv, interval) \
do {
/* TODO: add overflow and truncation checks */
\
tv.tv_usec += (long) interval; \
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 PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv)
#else
#define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
#endif
/* These private functions are implemented in Python/thread_pthread.h */
int
_PyThread_cond_init
(
PyCOND_T
*
cond
);
void
_PyThread_cond_after
(
long
long
us
,
struct
timespec
*
abs
);
/* The following functions return 0 on success, nonzero on error */
#define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL)
...
...
@@ -68,7 +58,7 @@ do { /* TODO: add overflow and truncation checks */ \
#define PyMUTEX_LOCK(mut) pthread_mutex_lock(mut)
#define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut)
#define PyCOND_INIT(cond)
pthread_cond_init((cond), NULL
)
#define PyCOND_INIT(cond)
_PyThread_cond_init(cond
)
#define PyCOND_FINI(cond) pthread_cond_destroy(cond)
#define PyCOND_SIGNAL(cond) pthread_cond_signal(cond)
#define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond)
...
...
@@ -78,22 +68,16 @@ do { /* TODO: add overflow and truncation checks */ \
Py_LOCAL_INLINE
(
int
)
PyCOND_TIMEDWAIT
(
PyCOND_T
*
cond
,
PyMUTEX_T
*
mut
,
long
long
us
)
{
int
r
;
struct
timespec
ts
;
struct
timeval
deadline
;
PyCOND_GETTIMEOFDAY
(
&
deadline
);
PyCOND_ADD_MICROSECONDS
(
deadline
,
us
);
ts
.
tv_sec
=
deadline
.
tv_sec
;
ts
.
tv_nsec
=
deadline
.
tv_usec
*
1000
;
r
=
pthread_cond_timedwait
((
cond
),
(
mut
),
&
ts
);
if
(
r
==
ETIMEDOUT
)
struct
timespec
abs
;
_PyThread_cond_after
(
us
,
&
abs
);
int
ret
=
pthread_cond_timedwait
(
cond
,
mut
,
&
abs
);
if
(
ret
==
ETIMEDOUT
)
{
return
1
;
else
if
(
r
)
}
if
(
ret
)
{
return
-
1
;
else
return
0
;
}
return
0
;
}
#elif defined(NT_THREADS)
...
...
Python/thread_pthread.h
View file @
001fee14
...
...
@@ -56,16 +56,6 @@
#endif
#endif
#if !defined(pthread_attr_default)
# define pthread_attr_default ((pthread_attr_t *)NULL)
#endif
#if !defined(pthread_mutexattr_default)
# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
#endif
#if !defined(pthread_condattr_default)
# define pthread_condattr_default ((pthread_condattr_t *)NULL)
#endif
/* Whether or not to use semaphores directly rather than emulating them with
* mutexes and condition variables:
...
...
@@ -110,6 +100,56 @@ do { \
} while(0)
/*
* pthread_cond support
*/
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
// monotonic is supported statically. It doesn't mean it works on runtime.
#define CONDATTR_MONOTONIC
#endif
// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
static
pthread_condattr_t
*
condattr_monotonic
=
NULL
;
static
void
init_condattr
()
{
#ifdef CONDATTR_MONOTONIC
static
pthread_condattr_t
ca
;
pthread_condattr_init
(
&
ca
);
if
(
pthread_condattr_setclock
(
&
ca
,
CLOCK_MONOTONIC
)
==
0
)
{
condattr_monotonic
=
&
ca
;
// Use monotonic clock
}
#endif
}
int
_PyThread_cond_init
(
PyCOND_T
*
cond
)
{
return
pthread_cond_init
(
cond
,
condattr_monotonic
);
}
void
_PyThread_cond_after
(
long
long
us
,
struct
timespec
*
abs
)
{
#ifdef CONDATTR_MONOTONIC
if
(
condattr_monotonic
)
{
clock_gettime
(
CLOCK_MONOTONIC
,
abs
);
abs
->
tv_sec
+=
us
/
1000000
;
abs
->
tv_nsec
+=
(
us
%
1000000
)
*
1000
;
abs
->
tv_sec
+=
abs
->
tv_nsec
/
1000000000
;
abs
->
tv_nsec
%=
1000000000
;
return
;
}
#endif
struct
timespec
ts
;
MICROSECONDS_TO_TIMESPEC
(
us
,
ts
);
*
abs
=
ts
;
}
/* A pthread mutex isn't sufficient to model the Python lock type
* because, according to Draft 5 of the docs (P1003.4a/D5), both of the
* following are undefined:
...
...
@@ -146,6 +186,7 @@ PyThread__init_thread(void)
extern
void
pthread_init
(
void
);
pthread_init
();
#endif
init_condattr
();
}
/*
...
...
@@ -462,8 +503,7 @@ PyThread_allocate_lock(void)
memset
((
void
*
)
lock
,
'\0'
,
sizeof
(
pthread_lock
));
lock
->
locked
=
0
;
status
=
pthread_mutex_init
(
&
lock
->
mut
,
pthread_mutexattr_default
);
status
=
pthread_mutex_init
(
&
lock
->
mut
,
NULL
);
CHECK_STATUS_PTHREAD
(
"pthread_mutex_init"
);
/* Mark the pthread mutex underlying a Python mutex as
pure happens-before. We can't simply mark the
...
...
@@ -472,8 +512,7 @@ PyThread_allocate_lock(void)
will cause errors. */
_Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX
(
&
lock
->
mut
);
status
=
pthread_cond_init
(
&
lock
->
lock_released
,
pthread_condattr_default
);
status
=
_PyThread_cond_init
(
&
lock
->
lock_released
);
CHECK_STATUS_PTHREAD
(
"pthread_cond_init"
);
if
(
error
)
{
...
...
@@ -532,9 +571,10 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
success
=
PY_LOCK_ACQUIRED
;
}
else
if
(
microseconds
!=
0
)
{
struct
timespec
ts
;
if
(
microseconds
>
0
)
MICROSECONDS_TO_TIMESPEC
(
microseconds
,
ts
);
struct
timespec
abs
;
if
(
microseconds
>
0
)
{
_PyThread_cond_after
(
microseconds
,
&
abs
);
}
/* continue trying until we get the lock */
/* mut must be locked by me -- part of the condition
...
...
@@ -543,10 +583,13 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
if
(
microseconds
>
0
)
{
status
=
pthread_cond_timedwait
(
&
thelock
->
lock_released
,
&
thelock
->
mut
,
&
ts
);
&
thelock
->
mut
,
&
abs
);
if
(
status
==
1
)
{
break
;
}
if
(
status
==
ETIMEDOUT
)
break
;
CHECK_STATUS_PTHREAD
(
"pthread_cond_timed
_
wait"
);
CHECK_STATUS_PTHREAD
(
"pthread_cond_timedwait"
);
}
else
{
status
=
pthread_cond_wait
(
...
...
configure
View file @
001fee14
...
...
@@ -11448,7 +11448,8 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
memrchr mbrtowc mkdirat
mkfifo
\
mkfifoat
mknod
mknodat mktime mremap
nice
openat pathconf pause pipe2 plock poll
\
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2
\
pthread_init pthread_kill putenv pwrite pwritev pwritev2
readlink
readlinkat readv
realpath
renameat
\
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2
\
readlink
readlinkat readv
realpath
renameat
\
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid
\
setgid sethostname
\
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf
\
...
...
configure.ac
View file @
001fee14
...
...
@@ -3506,7 +3506,8 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
memrchr mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_init pthread_kill putenv pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
...
...
pyconfig.h.in
View file @
001fee14
...
...
@@ -765,6 +765,9 @@
/* Define if your compiler supports function prototype */
#undef HAVE_PROTOTYPES
/* Define to 1 if you have the `pthread_condattr_setclock' function. */
#undef HAVE_PTHREAD_CONDATTR_SETCLOCK
/* Defined for Solaris 2.6 bug in pthread header. */
#undef HAVE_PTHREAD_DESTRUCTOR
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment