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 @@
namespace pyston {
namespace threading {
#define THREADING_USE_GIL 0
#define THREADING_SAFE_DATASTRUCTURES 0
#define THREADING_USE_GIL 1
#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
inline void ensureSerial() {
inline void acquireGLRead() {
acquireGLWrite();
}
inline void releaseGLRead() {
releaseGLWrite();
}
inline void promoteGL() {
}
inline void endEnsureSerial() {
inline void demoteGL() {
}
#endif
class SerialRegion {
public:
SerialRegion() { ensureSerial(); }
~SerialRegion() { endEnsureSerial(); }
#define MAKE_REGION(name, start, end) \
class name {\
public:\
name() { start(); }\
~name() { end(); }\
};
class UnSerialRegion {
public:
UnSerialRegion() { endEnsureSerial(); }
~UnSerialRegion() { ensureSerial(); }
};
void allowThreads();
void endAllowThreads();
class AllowThreadsRegion {
public:
AllowThreadsRegion() { allowThreads(); }
~AllowThreadsRegion() { endAllowThreads(); }
};
MAKE_REGION(GLReadRegion, acquireGLRead, releaseGLRead);
MAKE_REGION(GLPromoteRegion, promoteGL, demoteGL);
MAKE_REGION(GLReadReleaseRegion, releaseGLRead, acquireGLRead);
MAKE_REGION(GLWriteReleaseRegion, releaseGLWrite, acquireGLWrite);
#undef MAKE_REGION
} // namespace threading
} // namespace pyston
......
......@@ -32,6 +32,7 @@
#include "core/common.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/threading.h"
#include "core/types.h"
#include "core/util.h"
......@@ -107,6 +108,8 @@ int main(int argc, char** argv) {
// end of argument parsing
threading::GLReadRegion _glock;
_t.split("to run");
if (fn != NULL) {
BoxedModule* main = createModule("__main__", fn);
......
......@@ -30,6 +30,8 @@ static_assert(sizeof(pthread_t) <= sizeof(BoxedInt::n), "");
BoxedModule* thread_module;
static void* thread_start(void* _args) {
threading::GLReadRegion _glock;
std::vector<Box*>* args = static_cast<std::vector<Box*>*>(_args);
assert(args->size() == 2 || args->size() == 3);
Box* target = (*args)[0];
......
......@@ -17,6 +17,7 @@
#include <sys/time.h>
#include "codegen/compvars.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
......@@ -50,8 +51,13 @@ Box* timeSleep(Box* arg) {
req.tv_sec = (int)(fullsecs + 0.01);
req.tv_nsec = (int)(nanosecs * 1000000000);
int code = nanosleep(&req, NULL);
ASSERT(code == 0, "%d", code);
int code;
{
threading::GLReadReleaseRegion _allow_threads;
code = nanosleep(&req, NULL);
}
RELEASE_ASSERT(code == 0, "%d", code);
return None;
}
......
......@@ -19,6 +19,7 @@
#include "Python.h"
#include "codegen/compvars.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/types.h"
......@@ -46,6 +47,8 @@ public:
assert(self->cls == capifunc_cls);
assert(varargs->cls == tuple_cls);
threading::GLPromoteRegion _gil_lock;
Box* rtn = (Box*)self->func(test_module, varargs);
assert(rtn);
return rtn;
......
......@@ -9,7 +9,6 @@ import time
work = []
done = []
def run(num):
work.append(num)
for i in xrange(num):
t = work.pop()
work.append(t - 1)
......@@ -18,6 +17,8 @@ def run(num):
print "starting!"
nthreads = 2
for i in xrange(nthreads):
work.append(1000000)
for i in xrange(nthreads):
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