Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
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
Boxiang Sun
Pyston
Commits
fe5fc746
Commit
fe5fc746
authored
Aug 20, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Purge the old GRWL (gil-free) code
It's time :(
parent
d7be5092
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
31 additions
and
211 deletions
+31
-211
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+0
-2
src/codegen/codegen.h
src/codegen/codegen.h
+0
-2
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+14
-26
src/core/threading.cpp
src/core/threading.cpp
+15
-95
src/core/threading.h
src/core/threading.h
+1
-75
src/jit.cpp
src/jit.cpp
+0
-6
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+0
-2
test/unittests/unittests.h
test/unittests/unittests.h
+1
-3
No files found.
src/codegen/codegen.cpp
View file @
fe5fc746
...
...
@@ -37,8 +37,6 @@
namespace
pyston
{
DS_DEFINE_RWLOCK
(
codegen_rwlock
);
FunctionMetadata
::
FunctionMetadata
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
std
::
unique_ptr
<
SourceInfo
>
source
)
:
code_obj
(
NULL
),
...
...
src/codegen/codegen.h
View file @
fe5fc746
...
...
@@ -90,8 +90,6 @@ extern GlobalState g;
// in runtime_hooks.cpp:
void
initGlobalFuncs
(
GlobalState
&
g
);
DS_DECLARE_RWLOCK
(
codegen_rwlock
);
}
#endif
src/codegen/irgen/hooks.cpp
View file @
fe5fc746
...
...
@@ -341,30 +341,26 @@ CompiledFunction* compileFunction(FunctionMetadata* f, FunctionSpecialization* s
void
compileAndRunModule
(
AST_Module
*
m
,
BoxedModule
*
bm
)
{
FunctionMetadata
*
md
;
{
// scope for limiting the locked region:
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
Timer
_t
(
"for compileModule()"
);
Timer
_t
(
"for compileModule()"
);
const
char
*
fn
=
PyModule_GetFilename
(
bm
);
RELEASE_ASSERT
(
fn
,
""
);
const
char
*
fn
=
PyModule_GetFilename
(
bm
);
RELEASE_ASSERT
(
fn
,
""
);
FutureFlags
future_flags
=
getFutureFlags
(
m
->
body
,
fn
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
m
,
true
);
FutureFlags
future_flags
=
getFutureFlags
(
m
->
body
,
fn
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
m
,
true
);
auto
fn_str
=
boxString
(
fn
);
AUTO_DECREF
(
fn_str
);
std
::
unique_ptr
<
SourceInfo
>
si
(
new
SourceInfo
(
bm
,
scoping
,
future_flags
,
m
,
fn_str
));
auto
fn_str
=
boxString
(
fn
);
AUTO_DECREF
(
fn_str
);
std
::
unique_ptr
<
SourceInfo
>
si
(
new
SourceInfo
(
bm
,
scoping
,
future_flags
,
m
,
fn_str
));
static
BoxedString
*
doc_str
=
getStaticString
(
"__doc__"
);
bm
->
setattr
(
doc_str
,
autoDecref
(
si
->
getDocString
()),
NULL
);
static
BoxedString
*
doc_str
=
getStaticString
(
"__doc__"
);
bm
->
setattr
(
doc_str
,
autoDecref
(
si
->
getDocString
()),
NULL
);
static
BoxedString
*
builtins_str
=
getStaticString
(
"__builtins__"
);
if
(
!
bm
->
hasattr
(
builtins_str
))
bm
->
setattr
(
builtins_str
,
PyModule_GetDict
(
builtins_module
),
NULL
);
static
BoxedString
*
builtins_str
=
getStaticString
(
"__builtins__"
);
if
(
!
bm
->
hasattr
(
builtins_str
))
bm
->
setattr
(
builtins_str
,
PyModule_GetDict
(
builtins_module
),
NULL
);
md
=
new
FunctionMetadata
(
0
,
false
,
false
,
std
::
move
(
si
));
}
md
=
new
FunctionMetadata
(
0
,
false
,
false
,
std
::
move
(
si
));
UNAVOIDABLE_STAT_TIMER
(
t0
,
"us_timer_interpreted_module_toplevel"
);
Box
*
r
=
astInterpretFunction
(
md
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
...
...
@@ -395,8 +391,6 @@ Box* evalOrExec(FunctionMetadata* md, Box* globals, Box* boxedLocals) {
static
FunctionMetadata
*
compileForEvalOrExec
(
AST
*
source
,
llvm
::
ArrayRef
<
AST_stmt
*>
body
,
BoxedString
*
fn
,
PyCompilerFlags
*
flags
)
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
Timer
_t
(
"for evalOrExec()"
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
source
,
false
);
...
...
@@ -655,8 +649,6 @@ void exec(Box* boxedCode, Box* globals, Box* locals, FutureFlags caller_future_f
// TODO we should have logic like this at the CLFunc level that detects that we keep
// on creating functions with failing speculations, and then stop speculating.
void
CompiledFunction
::
speculationFailed
()
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
this
->
times_speculation_failed
++
;
if
(
this
->
times_speculation_failed
==
4
)
{
...
...
@@ -735,8 +727,6 @@ ConcreteCompilerType* CompiledFunction::getReturnType() {
/// The cf must be an active version in its parents FunctionMetadata; the given
/// version will be replaced by the new version, which will be returned.
static
CompiledFunction
*
_doReopt
(
CompiledFunction
*
cf
,
EffortLevel
new_effort
)
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
assert
(
cf
->
md
->
versions
.
size
());
assert
(
cf
);
...
...
@@ -773,8 +763,6 @@ static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel new_effort)
static
StatCounter
stat_osrexits
(
"num_osr_exits"
);
static
StatCounter
stat_osr_compiles
(
"num_osr_compiles"
);
CompiledFunction
*
compilePartialFuncInternal
(
OSRExit
*
exit
)
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
assert
(
exit
);
stat_osrexits
.
log
();
...
...
src/core/threading.cpp
View file @
fe5fc746
...
...
@@ -36,6 +36,8 @@
namespace
pyston
{
namespace
threading
{
void
_acquireGIL
();
void
_releaseGIL
();
#ifdef WITH_THREAD
#include "pythread.h"
...
...
@@ -99,14 +101,14 @@ public:
return
holds_gil
;
}
void
takeGil
()
{
void
gilTaken
()
{
assert
(
pthread_self
()
==
this
->
pthread_id
);
assert
(
!
holds_gil
);
holds_gil
=
true
;
}
void
releaseGil
()
{
void
gilReleased
()
{
assert
(
pthread_self
()
==
this
->
pthread_id
);
assert
(
holds_gil
);
...
...
@@ -197,7 +199,7 @@ extern "C" PyGILState_STATE PyGILState_Ensure(void) noexcept {
if
(
current_internal_thread_state
==
NULL
)
Py_FatalError
(
"Couldn't create thread-state for new thread"
);
acquireGLRead
();
_acquireGIL
();
return
PyGILState_UNLOCKED
;
}
else
{
++
cur_thread_state
.
gilstate_counter
;
...
...
@@ -246,13 +248,14 @@ static void* _thread_start(void* _arg) {
Box
*
arg3
=
arg
->
arg3
;
delete
arg
;
threading
::
GLReadRegion
_glock
;
_acquireGIL
()
;
registerThread
(
true
);
assert
(
!
PyErr_Occurred
());
void
*
rtn
=
start_func
(
arg1
,
arg2
,
arg3
);
unregisterThread
();
_releaseGIL
();
return
rtn
;
}
...
...
@@ -296,6 +299,8 @@ void registerMainThread() {
assert
(
!
current_internal_thread_state
);
current_internal_thread_state
=
new
ThreadStateInternal
(
pthread_self
(),
&
cur_thread_state
);
current_threads
[
pthread_self
()]
=
current_internal_thread_state
;
_acquireGIL
();
}
/* Wait until threading._shutdown completes, provided
...
...
@@ -344,28 +349,23 @@ extern "C" void beginAllowThreads() noexcept {
LOCK_REGION
(
&
threading_lock
);
assert
(
current_internal_thread_state
);
current_internal_thread_state
->
releaseGil
();
current_internal_thread_state
->
gilReleased
();
}
releaseGLRead
();
_releaseGIL
();
}
extern
"C"
void
endAllowThreads
()
noexcept
{
acquireGLRead
();
_acquireGIL
();
{
LOCK_REGION
(
&
threading_lock
);
assert
(
current_internal_thread_state
);
current_internal_thread_state
->
takeGil
();
current_internal_thread_state
->
gilTaken
();
}
}
#if THREADING_USE_GIL
#if THREADING_USE_GRWL
#error "Can't turn on both the GIL and the GRWL!"
#endif
static
pthread_mutex_t
gil
=
PTHREAD_MUTEX_INITIALIZER
;
std
::
atomic
<
int
>
threads_waiting_on_gil
(
0
);
...
...
@@ -423,7 +423,7 @@ extern "C" void PyEval_ReInitThreads() noexcept {
Py_DECREF
(
threading
);
}
void
acquireGLWrite
()
{
void
_acquireGIL
()
{
threads_waiting_on_gil
++
;
pthread_mutex_lock
(
&
gil
);
threads_waiting_on_gil
--
;
...
...
@@ -431,7 +431,7 @@ void acquireGLWrite() {
pthread_cond_signal
(
&
gil_acquired
);
}
void
releaseGLWrite
()
{
void
_releaseGIL
()
{
pthread_mutex_unlock
(
&
gil
);
}
...
...
@@ -457,86 +457,6 @@ void _allowGLReadPreemption() {
threads_waiting_on_gil
--
;
pthread_cond_signal
(
&
gil_acquired
);
}
#elif THREADING_USE_GRWL
static
pthread_rwlock_t
grwl
=
PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
;
enum
class
GRWLHeldState
{
N
,
R
,
W
,
};
static
__thread
GRWLHeldState
grwl_state
=
GRWLHeldState
::
N
;
static
std
::
atomic
<
int
>
writers_waiting
(
0
);
void
acquireGLRead
()
{
assert
(
grwl_state
==
GRWLHeldState
::
N
);
pthread_rwlock_rdlock
(
&
grwl
);
grwl_state
=
GRWLHeldState
::
R
;
}
void
releaseGLRead
()
{
assert
(
grwl_state
==
GRWLHeldState
::
R
);
pthread_rwlock_unlock
(
&
grwl
);
grwl_state
=
GRWLHeldState
::
N
;
}
void
acquireGLWrite
()
{
assert
(
grwl_state
==
GRWLHeldState
::
N
);
writers_waiting
++
;
pthread_rwlock_wrlock
(
&
grwl
);
writers_waiting
--
;
grwl_state
=
GRWLHeldState
::
W
;
}
void
releaseGLWrite
()
{
assert
(
grwl_state
==
GRWLHeldState
::
W
);
pthread_rwlock_unlock
(
&
grwl
);
grwl_state
=
GRWLHeldState
::
N
;
}
void
promoteGL
()
{
Timer
_t2
(
"promoting"
,
/*min_usec=*/
10000
);
// Note: this is *not* the same semantics as normal promoting, on purpose.
releaseGLRead
();
acquireGLWrite
();
long
promote_us
=
_t2
.
end
();
static
thread_local
StatPerThreadCounter
sc_promoting_us
(
"grwl_promoting_us"
);
sc_promoting_us
.
log
(
promote_us
);
}
void
demoteGL
()
{
releaseGLWrite
();
acquireGLRead
();
}
static
__thread
int
gl_check_count
=
0
;
void
allowGLReadPreemption
()
{
assert
(
grwl_state
==
GRWLHeldState
::
R
);
// gl_check_count++;
// if (gl_check_count < 10)
// return;
// gl_check_count = 0;
if
(
__builtin_expect
(
!
writers_waiting
.
load
(
std
::
memory_order_relaxed
),
1
))
return
;
Timer
_t2
(
"preempted"
,
/*min_usec=*/
10000
);
pthread_rwlock_unlock
(
&
grwl
);
// The GRWL is a writer-prefered rwlock, so this next statement will block even
// if the lock is in read mode:
pthread_rwlock_rdlock
(
&
grwl
);
long
preempt_us
=
_t2
.
end
();
static
thread_local
StatPerThreadCounter
sc_preempting_us
(
"grwl_preempt_us"
);
sc_preempting_us
.
log
(
preempt_us
);
}
#endif
// We don't support CPython's TLS (yet?)
extern
"C"
void
PyThread_ReInitTLS
(
void
)
noexcept
{
...
...
src/core/threading.h
View file @
fe5fc746
...
...
@@ -47,35 +47,10 @@ void finishMainThread();
bool
isMainThread
();
#ifndef THREADING_USE_GIL
#define THREADING_USE_GIL 1
#define THREADING_USE_GRWL 0
#endif
#define THREADING_SAFE_DATASTRUCTURES THREADING_USE_GRWL
#if THREADING_SAFE_DATASTRUCTURES
#define DS_DEFINE_MUTEX(name) pyston::threading::PthreadFastMutex name
#define DS_DECLARE_RWLOCK(name) extern pyston::threading::PthreadRWLock name
#define DS_DEFINE_RWLOCK(name) pyston::threading::PthreadRWLock name
#define DS_DEFINE_SPINLOCK(name) pyston::threading::PthreadSpinLock name
#else
#define DS_DEFINE_MUTEX(name) pyston::threading::NopLock name
#define DS_DECLARE_RWLOCK(name) extern pyston::threading::NopLock name
#define DS_DEFINE_RWLOCK(name) pyston::threading::NopLock name
#define DS_DEFINE_SPINLOCK(name) pyston::threading::NopLock name
#endif
void
acquireGLRead
();
void
releaseGLRead
();
void
acquireGLWrite
();
void
releaseGLWrite
();
void
_allowGLReadPreemption
();
#define GIL_CHECK_INTERVAL 1000
// Note: this doesn't need to be an atomic, since it should
// only be accessed by the thread that holds the gil:
extern
int
gil_check_count
;
...
...
@@ -104,25 +79,7 @@ extern "C" inline void allowGLReadPreemption() {
_allowGLReadPreemption
();
}
// Note: promoteGL is free to drop the lock and then reacquire
void
promoteGL
();
void
demoteGL
();
// Helper macro for creating a RAII wrapper around two functions.
#define MAKE_REGION(name, start, end) \
class name { \
public: \
name() { start(); } \
~name() { end(); } \
};
MAKE_REGION
(
GLReadRegion
,
acquireGLRead
,
releaseGLRead
);
MAKE_REGION
(
GLPromoteRegion
,
promoteGL
,
demoteGL
);
// MAKE_REGION(GLReadReleaseRegion, releaseGLRead, acquireGLRead);
// MAKE_REGION(GLWriteReleaseRegion, releaseGLWrite, acquireGLWrite);
#undef MAKE_REGION
extern
"C"
void
beginAllowThreads
()
noexcept
;
extern
"C"
void
endAllowThreads
()
noexcept
;
...
...
@@ -134,37 +91,6 @@ public:
};
#if THREADING_USE_GIL
inline
void
acquireGLRead
()
{
acquireGLWrite
();
}
inline
void
releaseGLRead
()
{
releaseGLWrite
();
}
inline
void
promoteGL
()
{
}
inline
void
demoteGL
()
{
}
#endif
#if !THREADING_USE_GIL && !THREADING_USE_GRWL
inline
void
acquireGLRead
()
{
}
inline
void
releaseGLRead
()
{
}
inline
void
acquireGLWrite
()
{
}
inline
void
releaseGLWrite
()
{
}
inline
void
promoteGL
()
{
}
inline
void
demoteGL
()
{
}
extern
"C"
inline
void
allowGLReadPreemption
()
__attribute__
((
visibility
(
"default"
)));
extern
"C"
inline
void
allowGLReadPreemption
()
{
}
#endif
extern
bool
forgot_refs_via_fork
;
}
// namespace threading
...
...
src/jit.cpp
View file @
fe5fc746
...
...
@@ -369,7 +369,6 @@ static int main(int argc, char** argv) noexcept {
const
char
*
fn
=
NULL
;
threading
::
registerMainThread
();
threading
::
acquireGLRead
();
Py_SetProgramName
(
argv
[
0
]);
...
...
@@ -540,11 +539,6 @@ static int main(int argc, char** argv) noexcept {
threading
::
finishMainThread
();
// Acquire the GIL to make sure we stop the other threads, since we will tear down
// data structures they are potentially running on.
// Note: we will purposefully not release the GIL on exiting.
threading
::
promoteGL
();
_t
.
split
(
"Py_Finalize"
);
Py_Finalize
();
...
...
src/runtime/objmodel.cpp
View file @
fe5fc746
...
...
@@ -3967,8 +3967,6 @@ static StatCounter slowpath_pickversion("slowpath_pickversion");
template
<
ExceptionStyle
S
>
static
CompiledFunction
*
pickVersion
(
FunctionMetadata
*
f
,
int
num_output_args
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
// if always_use_version is set use it even if the exception style does not match.
// But prefer using the correct style if both are available
if
(
f
->
always_use_version
.
get
(
S
))
...
...
test/unittests/unittests.h
View file @
fe5fc746
...
...
@@ -25,12 +25,10 @@ namespace pyston {
class
PystonTestEnvironment
:
public
testing
::
Environment
{
void
SetUp
()
override
{
threading
::
registerMainThread
();
threading
::
acquireGLRead
();
}
void
TearDown
()
override
{
threading
::
releaseGLRead
();
//
threading::releaseGLRead();
}
};
...
...
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