Commit fee15977 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add a gil

Don't worry, a non-gil version is coming.
Use a gil for now so we can start working on the other threading
requirements, such as GC.
parent 77f9705a
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "core/threading.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <pthread.h>
#include <stdint.h>
namespace pyston {
namespace threading {
#if THREADING_USE_GIL
pthread_mutex_t gil = PTHREAD_MUTEX_INITIALIZER;
void acquireGLWrite() {
pthread_mutex_lock(&gil);
}
void releaseGLWrite() {
pthread_mutex_unlock(&gil);
}
#endif
} // namespace threading
} // namespace pyston
...@@ -18,38 +18,45 @@ ...@@ -18,38 +18,45 @@
namespace pyston { namespace pyston {
namespace threading { namespace threading {
#define THREADING_USE_GIL 0 #define THREADING_USE_GIL 1
#define THREADING_SAFE_DATASTRUCTURES 0 #define THREADING_USE_GRWL 0
#define THREADING_SAFE_DATASTRUCTURES THREADING_USE_GRWL
void acquireGLRead();
void releaseGLRead();
void acquireGLWrite();
void releaseGLWrite();
// Note: promoteGL is free to drop the lock and then reacquire
void promoteGL();
void demoteGL();
void ensureSerial();
void endEnsureSerial();
#if THREADING_USE_GIL #if THREADING_USE_GIL
inline void ensureSerial() { inline void acquireGLRead() {
acquireGLWrite();
}
inline void releaseGLRead() {
releaseGLWrite();
}
inline void promoteGL() {
} }
inline void endEnsureSerial() { inline void demoteGL() {
} }
#endif #endif
class SerialRegion { #define MAKE_REGION(name, start, end) \
public: class name {\
SerialRegion() { ensureSerial(); } public:\
~SerialRegion() { endEnsureSerial(); } name() { start(); }\
~name() { end(); }\
}; };
class UnSerialRegion { MAKE_REGION(GLReadRegion, acquireGLRead, releaseGLRead);
public: MAKE_REGION(GLPromoteRegion, promoteGL, demoteGL);
UnSerialRegion() { endEnsureSerial(); } MAKE_REGION(GLReadReleaseRegion, releaseGLRead, acquireGLRead);
~UnSerialRegion() { ensureSerial(); } MAKE_REGION(GLWriteReleaseRegion, releaseGLWrite, acquireGLWrite);
}; #undef MAKE_REGION
void allowThreads();
void endAllowThreads();
class AllowThreadsRegion {
public:
AllowThreadsRegion() { allowThreads(); }
~AllowThreadsRegion() { endAllowThreads(); }
};
} // namespace threading } // namespace threading
} // namespace pyston } // namespace pyston
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "core/common.h" #include "core/common.h"
#include "core/options.h" #include "core/options.h"
#include "core/stats.h" #include "core/stats.h"
#include "core/threading.h"
#include "core/types.h" #include "core/types.h"
#include "core/util.h" #include "core/util.h"
...@@ -107,6 +108,8 @@ int main(int argc, char** argv) { ...@@ -107,6 +108,8 @@ int main(int argc, char** argv) {
// end of argument parsing // end of argument parsing
threading::GLReadRegion _glock;
_t.split("to run"); _t.split("to run");
if (fn != NULL) { if (fn != NULL) {
BoxedModule* main = createModule("__main__", fn); BoxedModule* main = createModule("__main__", fn);
......
...@@ -30,6 +30,8 @@ static_assert(sizeof(pthread_t) <= sizeof(BoxedInt::n), ""); ...@@ -30,6 +30,8 @@ static_assert(sizeof(pthread_t) <= sizeof(BoxedInt::n), "");
BoxedModule* thread_module; BoxedModule* thread_module;
static void* thread_start(void* _args) { static void* thread_start(void* _args) {
threading::GLReadRegion _glock;
std::vector<Box*>* args = static_cast<std::vector<Box*>*>(_args); std::vector<Box*>* args = static_cast<std::vector<Box*>*>(_args);
assert(args->size() == 2 || args->size() == 3); assert(args->size() == 2 || args->size() == 3);
Box* target = (*args)[0]; Box* target = (*args)[0];
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <sys/time.h> #include <sys/time.h>
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "core/threading.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/gc_runtime.h" #include "runtime/gc_runtime.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
...@@ -50,8 +51,13 @@ Box* timeSleep(Box* arg) { ...@@ -50,8 +51,13 @@ Box* timeSleep(Box* arg) {
req.tv_sec = (int)(fullsecs + 0.01); req.tv_sec = (int)(fullsecs + 0.01);
req.tv_nsec = (int)(nanosecs * 1000000000); req.tv_nsec = (int)(nanosecs * 1000000000);
int code = nanosleep(&req, NULL); int code;
ASSERT(code == 0, "%d", code); {
threading::GLReadReleaseRegion _allow_threads;
code = nanosleep(&req, NULL);
}
RELEASE_ASSERT(code == 0, "%d", code);
return None; return None;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "Python.h" #include "Python.h"
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "core/threading.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -46,6 +47,8 @@ public: ...@@ -46,6 +47,8 @@ public:
assert(self->cls == capifunc_cls); assert(self->cls == capifunc_cls);
assert(varargs->cls == tuple_cls); assert(varargs->cls == tuple_cls);
threading::GLPromoteRegion _gil_lock;
Box* rtn = (Box*)self->func(test_module, varargs); Box* rtn = (Box*)self->func(test_module, varargs);
assert(rtn); assert(rtn);
return rtn; return rtn;
......
...@@ -9,7 +9,6 @@ import time ...@@ -9,7 +9,6 @@ import time
work = [] work = []
done = [] done = []
def run(num): def run(num):
work.append(num)
for i in xrange(num): for i in xrange(num):
t = work.pop() t = work.pop()
work.append(t - 1) work.append(t - 1)
...@@ -18,6 +17,8 @@ def run(num): ...@@ -18,6 +17,8 @@ def run(num):
print "starting!" print "starting!"
nthreads = 2 nthreads = 2
for i in xrange(nthreads):
work.append(1000000)
for i in xrange(nthreads): for i in xrange(nthreads):
t = start_new_thread(run, (1000000,)) t = start_new_thread(run, (1000000,))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment