Skip to content

Commit

Permalink
Stop using OpenMP in the system runtime - use pthreads instead to avo…
Browse files Browse the repository at this point in the history
…id problems with linkers and library versions trying to mix compilers

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@18243 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Nov 22, 2013
1 parent 818db31 commit 07461df
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
2 changes: 0 additions & 2 deletions Compiler/runtime/Makefile.common
Expand Up @@ -64,9 +64,7 @@ Print_omc.o : printimpl.c
Error_rml.o : errorext.cpp ErrorMessage.hpp
Error_omc.o : errorext.cpp ErrorMessage.hpp ../OpenModelicaBootstrappingHeader.h
System_rml.o : System_rml.c systemimpl.c config.h errorext.h $(configUnix)
$(OMPCC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $<
System_omc.o : System_omc.c systemimpl.c config.h errorext.h $(configUnix) $(RML_COMPAT)
$(OMPCC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $<
Lapack_rml.o : lapackimpl.c config.h $(configUnix)
Lapack_omc.o : lapackimpl.c config.h $(configUnix) $(RML_COMPAT)
IOStreamExt_rml.o : IOStreamExt.c
Expand Down
51 changes: 45 additions & 6 deletions Compiler/runtime/systemimpl.c
Expand Up @@ -594,6 +594,28 @@ int System_numProcessors(void)
#endif
}

struct systemCallWorkerThreadArgs {
pthread_mutex_t *mutex;
int *current;
int size;
char **calls;
int *results;
};

static void* systemCallWorkerThread(void *argVoid)
{
struct systemCallWorkerThreadArgs *arg = (struct systemCallWorkerThreadArgs *) argVoid;
while (1) {
int i;
pthread_mutex_lock(arg->mutex);
i = arg->current++;
pthread_mutex_unlock(arg->mutex);
if (i >= arg->size) break;
arg->results[i] = SystemImpl__systemCall(arg->calls[i]);
};
return NULL;
}

void* SystemImpl__systemCallParallel(void *lst, int numThreads)
{
void *tmp = lst;
Expand All @@ -605,26 +627,43 @@ void* SystemImpl__systemCallParallel(void *lst, int numThreads)
tmp = RML_CDR(tmp);
}
if (sz == 0) return mk_nil();
calls = (char**) GC_malloc(sz*sizeof(char*));
calls = (char**) GC_malloc(sz*sizeof(char*)+1);
assert(calls);
results = (int*) GC_malloc_atomic(sz*sizeof(int));
assert(results);
tmp = lst;
sz = 0;
if (numThreads > sz) {
numThreads = sz;
}
while (RML_NILHDR != RML_GETHDR(tmp)) {
calls[sz++] = RML_STRINGDATA(RML_CAR(tmp));
tmp = RML_CDR(tmp);
}
#pragma omp parallel for private(i) schedule(dynamic) num_threads(numThreads)
for (i=0; i<sz; i++) {
/* fprintf(stderr, "Starting call %s\n", calls[i]); */
results[i] = SystemImpl__systemCall(calls[i]);
/* fprintf(stderr, "Finished call %d %s=%d\n", i, calls[i], results[i]); */
if (sz == 1) {
results[i] = SystemImpl__systemCall(calls[0]);
} else {
int index;
pthread_mutex_t mutex;
struct systemCallWorkerThreadArgs args = {&mutex,&index,sz,calls,results};
pthread_mutex_init(&mutex,NULL);
pthread_t *th = GC_malloc(numThreads);
/* Last element is NULL from GC_malloc */
for (i=0; i<numThreads; i++) {
GC_pthread_create(&th[i],&args,systemCallWorkerThread,calls);
}
for (i=0; i<numThreads; i++) {
GC_pthread_join(th[i], NULL);
}
GC_free(th);
pthread_mutex_destroy(&mutex);
}
GC_free(calls);
tmp = mk_nil();
for (i=sz-1; i>=0; i--) {
tmp = mk_cons(mk_icon(results[i]),tmp);
}
GC_free(results);
return tmp;
}

Expand Down

0 comments on commit 07461df

Please sign in to comment.