[Tcl Java] Re: possible memory.

2000-10-27 Thread Mo DeJong

On Thu, 26 Oct 2000, Daniel Wickstrom wrote:

  "Mo" == Mo DeJong [EMAIL PROTECTED] writes:
 
 
 Mo Are you up to it? I am going to be working on this object ref
 Mo queue thing for some time, so if you could take a whack at the
 Mo Notifier it would really help. There is not going to be much
 Mo overlap in these changes, so they can be done in parallel.

 Ok here is a patch to make the notifier thread safe.  I've run the
 test cases on a solaris box, and it still fails with the same test
 cases that I posted earlier before I made the modifications.  Let me
 know what you think.

This patch looks great. I touched up a couple of little things
and checked it in (see the ChangeLog for the gory details).

I ran the tests again, and it looks like everything is working
just great. I can also run some multi-threaded tests that
did not work in the past.

Are there any remaining issues we need to look at before
merging this branch back into the HEAD? We can't fix
the ref count problem right now, we need to get this
all merged back into the HEAD and then we can look
at overhauling ref counting, perhaps on another branch.

Mo DeJong
Red Hat Inc


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-27 Thread Daniel Wickstrom

 "Mo" == Mo DeJong [EMAIL PROTECTED] writes:


Mo I ran the tests again, and it looks like everything is working
Mo just great. I can also run some multi-threaded tests that did
Mo not work in the past.

Mo Are there any remaining issues we need to look at before
Mo merging this branch back into the HEAD? We can't fix the ref
Mo count problem right now, we need to get this all merged back
Mo into the HEAD and then we can look at overhauling ref
Mo counting, perhaps on another branch.

This sounds promising.  As far as threading changes, there was the
issue of thread cleanup routine not being called.  Other than that
and the ref counting changes that you mentioned, I thinks that's it.
If I get a chance this weekend, I'll spend some time looking at the
thread cleanup issue.

-Dan


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-26 Thread Daniel Wickstrom

 "Mo" == Mo DeJong [EMAIL PROTECTED] writes:


Mo Are you up to it? I am going to be working on this object ref
Mo queue thing for some time, so if you could take a whack at the
Mo Notifier it would really help. There is not going to be much
Mo overlap in these changes, so they can be done in parallel.



Ok here is a patch to make the notifier thread safe.  I've run the
test cases on a solaris box, and it still fails with the same test
cases that I posted earlier before I made the modifications.  Let me
know what you think.

How is it going with the object ref queue thing?

-Dan


 notifier-patch.txt


[Tcl Java] Re: possible memory.

2000-10-24 Thread Jiang Wu

That may be true for your specific case.  Though, it is not true in general.
One could also potentially delete the interpreter without removing the
thread.  For example, one may be using a pool of Java threads to do some
work.  One thread is retrieved, creates a Tcl interp, do some work, delete
the interp, goes back into the thread pool.  The thread itself is never
deleted, only the resources used by the thread.

TclBlend allows a Tcl program to use Java.  It also needs to work the other
direction, which is allowing a Java program to use Tcl.

-- Jiang Wu
   [EMAIL PROTECTED]


 -Original Message-
 From: Dan Wickstrom [mailto:[EMAIL PROTECTED]]
 Sent: Sunday, October 22, 2000 11:53 AM
 To: [EMAIL PROTECTED]
 Cc: [EMAIL PROTECTED]
 Subject: [Tcl Java] Re: possible memory.
 
 
 Jiang Wu wrote:
 
  Let's not forget there is a problem with the putting object 
 on a queue for
  deletion by the interpreter.  As the GC may run at a random 
 time, it is
  possible when a Cobject is being finalized, the associated 
 interpreter is
  already deleted.
 
  1. Create a thread,
  2. Add a Tcl interpreter
  3. Do some Tcl work
  4. Delete the Tcl interpreter
  5. Delete the thread
 
  6. GC runs to finalize objects created in the above process
 
 
 It seems that we're preventing this by having the thread 
 cleanup routine detach
 the jvm thread.  All of the java objects would be finalized 
 when the thread was
 detached.  Of course, maybe I don't understand what you mean. 
  In aolserver,
 the case that you're talking about would never happen.
 
 
 -Dan
 
 
 The TclJava mailing list is sponsored by Scriptics Corporation.
 To subscribe:send mail to [EMAIL PROTECTED]  
  with the word SUBSCRIBE as the subject.
 To unsubscribe:  send mail to [EMAIL PROTECTED] 
  with the word UNSUBSCRIBE as the subject.
 To send to the list, send email to '[EMAIL PROTECTED]'. 
 An archive is available at 
 http://www.mail-archive.com/tcljava@scriptics.com
 


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-24 Thread Mo DeJong

On Tue, 24 Oct 2000, Jiang Wu wrote:

 That may be true for your specific case.  Though, it is not true in general.
 One could also potentially delete the interpreter without removing the
 thread.  For example, one may be using a pool of Java threads to do some
 work.  One thread is retrieved, creates a Tcl interp, do some work, delete
 the interp, goes back into the thread pool.  The thread itself is never
 deleted, only the resources used by the thread.
 
 TclBlend allows a Tcl program to use Java.  It also needs to work the other
 direction, which is allowing a Java program to use Tcl.
 
 -- Jiang Wu
[EMAIL PROTECTED]

Yeah, that is a nasty one. We really need to create a good document
that details all of these create/destroy cases.

In this case, the thread would hold the same notifier but
the interp it was create in would be different. I am not
sure if this would blow things up. It might be enough
to put a call to System.gc() in the Interp destroy
callback. Not only do we need to doc this, but we
need regression tests for these edge cases too. I
have been thinking about how to include thread
tests in the existing regression test suite, I
think a --with-thread option that points to
where the Thread extension is build is the
only way to go.

Mo DeJong
Red Hat Inc


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-22 Thread Dan Wickstrom

Mo DeJong wrote:

 On Sat, 21 Oct 2000, Dan Wickstrom wrote:

  
   What does your src/tclblend/tcl/lang/CObject.java finalize()
   method look like? I thought the last round of patches left
   that ptr dangling on purpose. I have not has time to
 
  Yes the finalize method just calls the super class finalize method.

 Well, that would be your memory leak :)

I realize that now, but I think the idea behind Jiang's reference counting changes
was to explicitly increment/decrement the reference count as needed similar to what
is done in the native tcl code.  I think there are still quite a few things that
need to be fixed to make this work, because the current code makes alot of
assumptions based on the fact that the CObject finalizer takes care of the Tcl_Obj
cleanup.  I think that it's still doable, but probably alot more work would be
needed to make the reference counting work right.


 Yes. The tricky part is going to be changing the C code to support
 this. We are going to need to have the ability to enque a TclEvent
 in the GC thread, but we need an interp handle for that.

 Here is that I am currently looking into:

 A CObject() is created by calling
 newInstance() from JNI code.
 But, we don't have a handle to
 an interp in the calling code.

 We need to wrap this into an
 object along with the interp
 handle and put it into a table
 somewhere so that the wrapped
 object can not get GCed.

 class CObjectCleanupTable {
   static void addObjRef(Interp i, long ptr)
   static void deleteObjRef(long ptr)
   static void finalizeObjRef(long ptr)
 }

 It seems like we could change the
 CObject.newInstance() signature, so
 that the Interp object would need
 to get passed along too.

 (Old)

 private static TclObject
 newInstance(
 long objPtr)// Tcl_Obj to wrap.
 {
 return new TclObject(new CObject(objPtr));
 }

 (New)

 private static TclObject
 newInstance(
 Interp interp,  // Current Interp
 long objPtr)// Tcl_Obj to wrap.
 {
 return new TclObject(new CObject(interp, objPtr));
 }

 This means that any place where CObject.newInstance()
 (only JavaGetTclObject at this point) is called would
 also need to include the Interp parameter.

 Now the CObject ctor could register the given objPtr
 like so:

 CObject(
 Interp interp,  // The current Interp
 long objPtr)// Pointer to Tcl_Obj from C.
 {
 this.objPtr = objPtr;
 incrRefCount(objPtr);
 CObjectCleanupTable.addObjRef(interp, objPtr);
 }

 Then in the finalize method we would do this:

 protected void finalize() throws Throwable
 {
 if (objPtr != 0) {
 /*
  * If the object is finalized while the reference is still valid,
  * we need to sever the connection to the underlying Tcl_Obj*.
  */

 CObjectCleanupTable.finalizeObjRef(objPtr);
 }
 super.finalize();
 }

 That would enqueue a TclEvent that would end up calling
 CObject.decrRefCount(objPtr) inside the thread where
 the Tcl_Obj was created.

 I think it is doable, but some hacking is going to
 be required.

It seems like it would work.

   We also need to make the Tcl Blend Notifier thread
   safe. I think time would be better spent focusing
   on that right now instead of fighting ref counting.
 
  Is this just a matter of modifying the Notifier class so that there
  is an event queue per thread instead of a global queue as there
  is now.  Are there any modifications necessary in the 'c' code?

 Making the Notifier "thread safe" is actually the easy part.
 All you would need to do is add another field to the Java
 interp structure that would store the "Tcl Thread ID" value.
 You would get the thread id in the pkg init code, and then save
 it into the Interp structure.

 ThreadID curThread;
 GetCurrentThread(curThread);
 /* put into interp field */

 This TclThreadID is needed so that you can call the
 Tcl_ThreadAlert(ThreadID) from inside the Notifier
 code.

 Once that bit is in place, you would then need to
 rip out the current notifier implementation.
 Start with the Jacl impl of Notifier and
 copy it into the Tcl Blend dir. Now merge any
 diffs over from the Tcl Blend impl but leave
 out all of the "global notifier" crap. The
 only thing to watch out for is to keep
 Jiang's fixed for deadlocking in the
 Notifier queue. I don't think that
 patch ever made it into Jacl so
 don't copy that bit (see ChangeLog
 entry on 2000-08-23).

 Now it is just a matter of going in a deleting
 all the unused C code that was used to implement
 the old notifier. That part should be fun cause
 there is just a gob of nasty code in there and
 one quick press of the delete button will finish
 it off.

 Are you up to it? I am going to be working on
 this object ref queue thing for some time,
 so if you could take a whack at the Notifier
 it would really help. There is not going to
 be much overlap in these changes, so they
 can be done in parallel.

I'll see if 

[Tcl Java] Re: possible memory.

2000-10-22 Thread Mo DeJong

On Sun, 22 Oct 2000, Jiang Wu wrote:

 Let's not forget there is a problem with the putting object on a queue for
 deletion by the interpreter.  As the GC may run at a random time, it is
 possible when a Cobject is being finalized, the associated interpreter is
 already deleted.
 
 1. Create a thread,
 2. Add a Tcl interpreter
 3. Do some Tcl work
 4. Delete the Tcl interpreter
 5. Delete the thread
 
 6. GC runs to finalize objects created in the above process

I agree that the case you describe is a concern, but I don't
see that we have a choice at this point. I would like to get
this free with the queue thing and fixing up of the Notifier
done, and then worry about overhauling the ref counting approach.
We need to get these changes finished off and merged back into
the HEAD very soon. Currently, we have no thread safe code to
point people to. Something that works for 99.999% of the cases
is better than something that works for 0% of them.

Mo DeJong
Red Hat Inc


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-21 Thread Mo DeJong

 On Sat, 21 Oct 2000, Dan Wickstrom wrote:
 
  
   What does your src/tclblend/tcl/lang/CObject.java finalize()
   method look like? I thought the last round of patches left
   that ptr dangling on purpose. I have not has time to
  
  Yes the finalize method just calls the super class finalize method.
 
 Well, that would be your memory leak :)

I finished an initial implementation of some code
that will put an object that needs to be decr'ed
into the event queue.

I have been getting some good results, the crashing
I was seeing with JDK 1.3 from IBM has now gone
away. I also ran it with some tests under JDK 1.1
and it is working (with one small exception).

Could some folks to try this out and see if it
makes the crash in the GC thread problem go away?
There should be no more memory leaks.

The patch is for src/tclblend/tcl/lang/CObject.java
off of the contract branch.

thanks
Mo DeJong
Red Hat Inc

Index: CObject.java
===
RCS file: /cvsroot/tcljava/tcljava/src/tclblend/tcl/lang/CObject.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 CObject.java
--- CObject.java1998/10/14 21:09:10 1.1.1.1
+++ CObject.java2000/10/22 02:25:36
@@ -24,11 +24,9 @@
 
 class CObject extends InternalRep {
 
-/*
- * This long really contains a Tcl_Obj*.  It is declared with package
- * visibility so that subclasses that define type specific functionality
- * can get to the Tcl_Obj.
- */
+// This long really contains a Tcl_Obj*.  It is declared with package
+// visibility so that subclasses that define type specific functionality
+// can get to the Tcl_Obj. This field can be read from C code.
 
 long objPtr;
 
@@ -51,8 +49,7 @@
 
 CObject()
 {
-this.objPtr = newCObject(null);
-incrRefCount(objPtr);
+this(newCObject(null));
 }
 
 /*
@@ -76,6 +73,9 @@
 {
 this.objPtr = objPtr;
 incrRefCount(objPtr);
+
+Notifier notifier = Notifier.getNotifierForThread(Thread.currentThread());
+addTableRef(notifier, objPtr);
 }
 
 /*
@@ -97,6 +97,7 @@
 public void
 dispose()
 {
+removeTableRef(objPtr);
 decrRefCount(objPtr);
 objPtr = 0;
 }
@@ -180,6 +181,7 @@
  * newInstance --
  *
  * Construct a new TclObject from a Tcl_Obj*.  This routine is only
+ * called from C. It is also the only CObject method that can be
  * called from C.
  *
  * Results:
@@ -218,11 +220,13 @@
 {
 if (objPtr != 0) {
/*
-* If the object is finalized while the reference is still valid, 
-* we need to sever the connection to the underlying Tcl_Obj*.
+* If a CObject is finalized while the reference is still valid, 
+* we need to send the reference back to the thread that created it.
+* We can then sever the connection to the underlying Tcl_Obj* by
+* calling decrRefCount() in that thread.
 */
 
-   decrRefCount(objPtr);
+   finalizeTableRef(objPtr);
 }
 super.finalize();
 }
@@ -329,6 +333,202 @@
 makeRef(
 long objPtr,   // Pointer to Tcl_Obj.
 TclObject object); // Object that Tcl_Obj should refer to.
+
+/*
+ *--
+ *
+ * CleanupTableEntry --
+ *
+ * This is a little helper class used to store the objPtr
+ * and to take on the role of the TclEvent that will be
+ * called after the event is queued.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--
+ */
+
+static class CleanupTableEntry extends TclEvent {
+Notifier notifier;
+long objPtr;
+
+CleanupTableEntry(Notifier notifier, long objPtr) {
+ this.notifier = notifier;
+ this.objPtr = objPtr;
+}  
+
+public int processEvent(int flags) {
+System.err.println("calling decrRefCount from processEvent for " + objPtr);
+CObject.decrRefCount(objPtr);
+return 1;
+}
+
+// This method will add this TclEvent to the
+// notifier for the Interp that created the
+// original Tcl_Obj ptr. This must be done
+// asyncronously, we can't block the GC
+// thread for any reason!
+
+void appendToNotifierQueue() {
+System.err.println("queueing cleanup for " + objPtr);
+   notifier.queueEvent(this, TCL.QUEUE_TAIL);
+}
+}
+
+/*
+ *--
+ *
+ * addTableRef --
+ *
+ * Create a ref in the global Tcl_Obj table. It is used to
+ * keep track of the interp where a given object was created
+ * so that we can queue up an event in that interp.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--
+ */
+
+private static void

[Tcl Java] Re: possible memory.

2000-10-20 Thread Mo DeJong

On Fri, 20 Oct 2000, Daniel Wickstrom wrote:

 The TclList.getLength method converts indexListObj to a TclList object
 which uses an underlying Tcl_Obj to hold the internal rep.  At the end
 of this case statement, it returns leaving indexListObj with no
 references.  The jvm garbage collects indexListObj, but the underlying
 Tcl_Obj is left stranded and results in a memory leak.
 
 -Dan

What does your src/tclblend/tcl/lang/CObject.java finalize()
method look like? I thought the last round of patches left
that ptr dangling on purpose. I have not has time to
look at the patches your guys are using so I am not
sure what is going on. I think what we need to do in the
short term is to implement a patch that will send a
Tcl_Obj that gets freed back to the Tcl interp using
the thread safe event queue. That way we can free the
object up back in the Tcl thread and it will not core
dump like it would if we freed it up in the JVM GC
thread. After we have something (anything) working
we can hack around with the various ref count
solutions to see if we can find one that passes
all the tests and does not leak memory.

We also need to make the Tcl Blend Notifier thread
safe. I think time would be better spent focusing
on that right now instead of fighting ref counting.

Mo DeJong
Red Hat Inc


The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:send mail to [EMAIL PROTECTED]  
 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com




[Tcl Java] Re: possible memory.

2000-10-19 Thread Dan Wickstrom

The last posting got mangled a little, so I'm attaching the trace file.  It's
probably a lot clearer than looking at my last posting.

-Dan




   0  ckalloc  8c5d99024./../generic/tclLiteral.c   261
   1  ckalloc  8c5d9d817./../generic/tclLiteral.c   267
   2  ckalloc  88f783812./../generic/tclLiteral.c   290
   3  ckalloc  8c5da2029./../generic/tclCompile.c  1737
   4  ckalloc  8c5da7024./../generic/tclLiteral.c   261
   5  ckalloc  8c5dab810./../generic/tclLiteral.c   267
   6  ckalloc  88f23e012./../generic/tclLiteral.c   290
   7  ckalloc  88f4ec024./../generic/tclExecute.c  4863: freed at  
  117
   8  ckalloc  88f4f0824./../generic/tclLiteral.c   261
   9  ckalloc  88f4f5021./../generic/tclLiteral.c   267
  10  ckalloc  88f4f9812./../generic/tclLiteral.c   290
  11  ckalloc  88f4fd831./../generic/tclCompile.c  1737
  12  ckalloc  86c830824./../generic/tclLiteral.c   261
  13  ckalloc  86c8350 9./../generic/tclLiteral.c   267
  14  ckalloc  86c839012./../generic/tclLiteral.c   290
  15  ckalloc  86c83d024./../generic/tclLiteral.c   261
  16  ckalloc  86c8418 4./../generic/tclLiteral.c   267
  17  ckalloc  86c845012./../generic/tclLiteral.c   290
  18  ckalloc  86a780024./../generic/tclLiteral.c   261
  19  ckalloc  86a784810./../generic/tclLiteral.c   267
  20  ckalloc  86a788812./../generic/tclLiteral.c   290
  21  ckalloc  86a78c824./../generic/tclLiteral.c   261
  22  ckalloc  86a7910 6./../generic/tclLiteral.c   267
  23  ckalloc  86a794812./../generic/tclLiteral.c   290
  24  ckalloc  8c5c51864./../generic/tclLiteral.c   845: freed at  
   75
  25  ckalloc  8c5c58830./../generic/tclCompile.c  1737
  26  ckalloc  8c5c5d824./../generic/tclLiteral.c   261
  27  ckalloc  8c5c62011./../generic/tclLiteral.c   267
  28  ckalloc  8c5c66012./../generic/tclLiteral.c   290
  29  ckalloc  8c55ad828./../generic/tclCompile.c  1737
  30  ckalloc  8c55b2824./../generic/tclLiteral.c   261
  31  ckalloc  8c55b70 9./../generic/tclLiteral.c   267
  32  ckalloc  8c55bb012./../generic/tclLiteral.c   290
  33  ckalloc  8c55bf024./../generic/tclLiteral.c   261
  34  ckalloc  8c55c3816./../generic/tclLiteral.c   267
  35  ckalloc  86abba012./../generic/tclLiteral.c   290
  36  ckalloc  86abbe026./../generic/tclCompile.c  1737
  37  ckalloc  86abc3024./../generic/tclLiteral.c   261
  38  ckalloc  86abc7812./../generic/tclLiteral.c   267
  39  ckalloc  86abcb812./../generic/tclLiteral.c   290
  40  ckalloc  86abcf824./../generic/tclLiteral.c   261
  41  ckalloc  868bca011./../generic/tclLiteral.c   267
  42  ckalloc  868bce012./../generic/tclLiteral.c   290
  43  ckalloc  868bd2024./../generic/tclExecute.c  4863: freed at  
  586
  44  ckalloc  868bd6824./../generic/tclLiteral.c   261
  45  ckalloc  868bdb020./../generic/tclLiteral.c   267
  46  ckalloc  868bdf812./../generic/tclLiteral.c   290
  47  ckalloc  868be3828./../generic/tclCompile.c  1737
  48  ckalloc  86a28d824./../generic/tclLiteral.c   261
  49  ckalloc  8c5c6a0 5./../generic/tclLiteral.c   267
  50  ckalloc  86a292012./../generic/tclLiteral.c   290
  51  ckalloc  86a296027./../generic/tclCompile.c  1737
  52  ckalloc  86a29b030./../generic/tclCompile.c  1737
  53  ckalloc  86a2a0024./../generic/tclLiteral.c   261
  54  ckalloc  86a2a48 4./../generic/tclLiteral.c   267
  55  ckalloc  86a2a8012./../generic/tclLiteral.c   290
  56  ckalloc  86a620824./../generic/tclLiteral.c   261
  57  ckalloc  86a6250 5./../generic/tclLiteral.c   267
  58  ckalloc  86a628812./../generic/tclLiteral.c   290
  59  ckalloc  86a62c824./../generic/tclLiteral.c   261
  60  ckalloc  86a6310 9./../generic/tclLiteral.c   267
  61  ckalloc  86a635012./../generic/tclLiteral.c   290
  62  ckalloc  86a639024./../generic/tclLiteral.c   261
  63