[m-dev.] for review: fix :- export with threads memory leak
Tyson Dowd
trd at cs.mu.OZ.AU
Wed Sep 27 15:12:03 AEDT 2000
Hi,
Roy Ward reported that MCORBA seemed to chew up 4Mb each time you call
it. This is a fix for that problem.
===================================================================
Estimated hours taken: 2.5
Fix a bug with :- export and threads.
Each time we called from C to Mercury, we initialized the thread engine
(if necessary).
This allocated a new context every time we entered Mercury.
Unfortunately, these contexts were never released, so every entry into
Mercury from C cost about 4Mb of memory (almost all of which is the
deterministic stack). In a busy CORBA application you would run out of
memory really quickly.
compiler/export.m:
When initializing threads, remember whether we are responsible
for finalizing the engine (e.g. if we are the first C->Mercury
call to create the engine, we'll be the last to exit it and should
clean up afterwards).
runtime/mercury_engine.c:
Finalize engines by destroying the context (this will put the
memory zones onto a free list).
runtime/mercury_thread.c:
runtime/mercury_thread.h:
Make init_thread return TRUE if an engine has been allocated and
it is the caller's responsibility to finialize it.
Index: compiler/export.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/export.m,v
retrieving revision 1.36
diff -u -r1.36 export.m
--- compiler/export.m 2000/08/30 07:19:52 1.36
+++ compiler/export.m 2000/09/27 02:45:59
@@ -118,11 +118,14 @@
% /* Word for input, Word* for output */
% {
% #if NUM_REAL_REGS > 0
- % Word c_regs[NUM_REAL_REGS];
+ % MR_Word c_regs[NUM_REAL_REGS];
% #endif
% #if FUNCTION
- % Word retval;
+ % MR_Word retval;
% #endif
+ % #if MR_THREAD_SAFE
+ % MR_Bool must_finalize_engine;
+ % #endif
%
% /* save the registers that our C caller may be using */
% save_regs_to_mem(c_regs);
@@ -134,7 +137,7 @@
% */
%
% #if MR_THREAD_SAFE
- % init_thread(MR_use_now);
+ % must_finalize_engine = init_thread(MR_use_now);
% #endif
%
% /*
@@ -166,6 +169,11 @@
% <copy return value register into retval>
% #endif
% <copy output args from registers into *Mercury__Arguments>
+ % #if MR_THREAD_SAFE
+ % if (must_finalize_engine) {
+ % finalize_thread_engine();
+ % }
+ % #endif
% restore_regs_from_mem(c_regs);
% #if SEMIDET
% return TRUE;
@@ -207,11 +215,14 @@
"#if NUM_REAL_REGS > 0\n",
"\tMR_Word c_regs[NUM_REAL_REGS];\n",
"#endif\n",
+ "#if MR_THREAD_SAFE\n",
+ "\tMR_Bool must_finalize_engine;\n",
+ "#endif\n",
MaybeDeclareRetval,
"\n",
"\tsave_regs_to_mem(c_regs);\n",
"#if MR_THREAD_SAFE\n",
- "\tinit_thread(MR_use_now);\n",
+ "\tmust_finalize_engine = init_thread(MR_use_now);\n",
"#endif\n",
"\trestore_registers();\n",
InputArgs,
@@ -221,6 +232,11 @@
"\trestore_transient_registers();\n",
MaybeFail,
OutputArgs,
+ "#if MR_THREAD_SAFE\n",
+ "\tif (must_finalize_engine) {\n",
+ "\t\t finalize_thread_engine();\n",
+ "\t}\n",
+ "#endif\n",
"\trestore_regs_from_mem(c_regs);\n",
MaybeSucceed,
"}\n\n"],
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_engine.c,v
retrieving revision 1.25
diff -u -r1.25 mercury_engine.c
--- runtime/mercury_engine.c 2000/09/14 11:12:16 1.25
+++ runtime/mercury_engine.c 2000/09/27 01:46:01
@@ -128,7 +128,7 @@
void finalize_engine(MercuryEngine *eng)
{
-
+ destroy_context(eng->this_context);
}
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_thread.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_thread.c,v
retrieving revision 1.12
diff -u -r1.12 mercury_thread.c
--- runtime/mercury_thread.c 2000/08/30 07:20:16 1.12
+++ runtime/mercury_thread.c 2000/09/27 01:47:40
@@ -66,7 +66,7 @@
#endif /* MR_THREAD_SAFE */
-void
+MR_Bool
init_thread(MR_when_to_use when_to_use)
{
MercuryEngine *eng;
@@ -78,7 +78,7 @@
** return, there's nothing for us to do.
*/
if (pthread_getspecific(MR_engine_base_key)) {
- return;
+ return FALSE;
}
#endif
eng = create_engine();
@@ -108,14 +108,31 @@
(void) MR_call_engine(ENTRY(do_runnext), FALSE);
destroy_engine(eng);
- return;
+ return FALSE;
case MR_use_now :
- return;
+ return TRUE;
default:
fatal_error("init_thread was passed a bad value");
}
+}
+
+/*
+** Release resources associated with this thread.
+** XXX calling destroy_engine(eng) appears to segfault.
+** This should probably be investigated and fixed.
+*/
+void
+finalize_thread_engine(void)
+{
+#ifdef MR_THREAD_SAFE
+ MercuryEngine *eng;
+
+ eng = pthread_getspecific(MR_engine_base_key);
+ pthread_setspecific(MR_engine_base_key, NULL);
+ finalize_engine(eng);
+#endif
}
#ifdef MR_THREAD_SAFE
Index: runtime/mercury_thread.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_thread.h,v
retrieving revision 1.7
diff -u -r1.7 mercury_thread.h
--- runtime/mercury_thread.h 2000/08/30 07:20:17 1.7
+++ runtime/mercury_thread.h 2000/09/27 01:45:10
@@ -130,10 +130,23 @@
/*
** Create and initialize a new Mercury engine running in the current
** POSIX thread.
+**
** See the comments above for the meaning of the argument.
** If there is already a Mercury engine running in the current POSIX
** thread then init_thread is just a no-op.
+**
+** Returns TRUE if a Mercury engine was created as a result of this
+** call *and* it is the caller's responsibility to finalize it (it is
+** intended that the caller can store the return value and call
+** finalize_thread_engine if it is true).
*/
-void init_thread(MR_when_to_use);
+int init_thread(MR_when_to_use);
+/*
+** Finalize the thread engine running in the current POSIX thread.
+** This will release the resources used by this thread -- this is very
+** important because the memory used for the det stack for each thread
+** can be re-used by the next init_thread.
+*/
+void finalize_thread_engine(void);
#endif
--
Tyson Dowd #
# Surreal humour isn't everyone's cup of fur.
trd at cs.mu.oz.au #
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list