Bug, bug... who's got the bug?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug, bug... who's got the bug?

mcbrides
Hey, found something here...

I was translating some java samples to netrexx and turned up a bug that I can
make "come and go" at will.

If I compile the listed script with "options binary" and then run it, the
program runs to the end and then just "sits there". If I add "exit" to the end
of the main() method, the program runs and terminates as expected when done.

Removing "options binary" and "exit" from the script, compile and run, and the
program also behaves as expected. That is, it runs and terminates when
completed. ??

Upon examining the .keep from both compiles, the very last line in both print-
outs are identical, I'm not sure where to go bug hunting just yet. I'm really
puzzled that it can be fixed by adding an "exit" to the main() method. Exit is
optional, isn't it? <G>

Now the odd part. By turning off the JIT, the program runs normally in both
compiles. ??

Platform; OS/2, NR1148, JDK117

Sample;

--
-- This netrexx script will compile with one warning. Will run to end and then
-- "hangout" till control-c from console...
--
-- Either adding "exit" to bottom of main class or turning JIT off will allow
-- successful temination upon completeion of program.
--
--
-- MyThread class that adds to a count variable
--
  options binary

  class MyThread extends Thread

    properties public

      count = int 0

--
-- getCount class returns the value of the count variable
--
    method getCount() returns int

      return count
--
-- thread that increments count variable "forever"
--
    method run()

      loop forever

        count = count + 1

        end

  class TimeSliced

    method main(args=string[]) static

      threshold = int

      -- create the threads
      System.out.println('Creating the threads...')
      Thread_a = MyThread()
      Thread_b = MyThread()

      -- make sure this thread can preempt the other
      System.out.println('Bumping main thread to MAX priority...')
      Thread.currentThread().setPriority(Thread.MAX_PRIORITY)

      -- start the threads
      System.out.println('Starting the threads...')
      Thread_a.start()
      Thread_b.start()

      -- sleep the main thread and give other threads a chance to increment count
      do
        System.out.println('Sleeping the main thread...')
        Thread.sleep(2000)
        catch e = InterruptedException
        end

      -- stop the threads
      System.out.println('Stopping the threads...')
      Thread_a.stop()
      Thread_b.stop()

      System.out.println('Thread_a: '||Thread_a.getCount())
      System.out.println('Thread_b: '||Thread_b.getCount())

      -- take the maximum counter value from each thread and
      -- set the threshold

      if (Thread_a.getCount() > Thread_b.getCount()) then
        threshold = Thread_a.getCount() * 2
          else
            threshold = Thread_b.getCount() * 2

      -- if the system is time sliced, the two values of the conters
      -- should be close to each other...

      if (Thread_a.getCount() >= Thread_b.getCount() - threshold & Thread_a.getCount() <= Thread_b.getCount() + threshold) then
        System.out.println('Your system is most likely time sliced.')
          else
            System.out.println('Your system is most likely NOT time sliced')
--
-- end of netrexx script
--
--
--

/--------------------\
| Jerry McBride      |
| [hidden email] |
\--------------------/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unsubscribe from this mailing list ( ibm-netrexx ), please send a note to
[hidden email]
with the following message in the body of the note
unsubscribe ibm-netrexx <e-mail address>

Reply | Threaded
Open this post in threaded view
|

Re: Bug, bug... who's got the bug?

Dr Tony Dahlman-2
Hi Jerry -

Whether extending the Thread class or implementing the
Runnable interface, you will have a "public void run()"
method.  Just return from run() - or get to the end of
it and return that way - and the thread will die
normally.

boolean doneEarly = false;
public void run() {
   // do some stuff
   
   // end thread if we're done early
   if( doneEarly )
      return;

   // do more stuff if not done yet

   // thread dies naturally here
}

- Tony Dahlman

Surgery, Surgeons and You <http://www.jps.net/adahlman/>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unsubscribe from this mailing list ( ibm-netrexx ), please send a note to
[hidden email]
with the following message in the body of the note
unsubscribe ibm-netrexx <e-mail address>

Reply | Threaded
Open this post in threaded view
|

Re: Bug, bug... who's got the bug?

mcbrides
>Hi Jerry -
>
>Whether extending the Thread class or implementing the
>Runnable interface, you will have a "public void run()"
>method.  Just return from run() - or get to the end of
>it and return that way - and the thread will die
>normally.
>
>boolean doneEarly = false;
>public void run() {
>   // do some stuff
>
>   // end thread if we're done early
>   if( doneEarly )
>      return;
>
>   // do more stuff if not done yet
>
>   // thread dies naturally here
>}

Hi Dr.

Actually, the code I write do have methods of terminating, similar to what you
suggest; running of the end, returning, etc.

However, what has me deeply puzzled is why this piece of SUN distributed
example code fails to terminate. By adding in some debug code, it looks like
the threads are never terminated, even after stop() is called on both running
threads. Very puzzling, to say the least. The thread object is a forever loop
that increments a counter, no returns, etc.

-- snip from the ported SUN sample...

method run() public

  loop forever
    count = count + 1
    end

However, surely even this thread model should be kill-able with a call to
stop()? But it's not... I tried various "fixes" like adding a sleep() to the
thread inside the loop, suspend() the thread before stop(), etc... However,
those threads fail to die before the main method completes, unless I add an
exit statement as the last line in the main method... I'll be darned if I know
where the problem is... the JDK or NetRexx...

Hmmm... Before I go, how would you port the following java method to NetRexx?


  public void run() {
  while (true)
  count++;
  }


--

/--------------------\
| Jerry McBride      |
| [hidden email] |
\--------------------/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unsubscribe from this mailing list ( ibm-netrexx ), please send a note to
[hidden email]
with the following message in the body of the note
unsubscribe ibm-netrexx <e-mail address>

Reply | Threaded
Open this post in threaded view
|

Re: Bug, bug... who's got the bug?

Dr Tony Dahlman-2
In reply to this post by mcbrides
Hi all -

Jerry wrote:
> method run() public
>
> loop forever
>    count = count + 1
>    end

I apologize.  My NetRexx coding skills have become pretty
rusty.  I think it's a great implementation for Rexx and the
ability to write cross-platform scripts that compile to Java
code is another (and unexpected) big plus for Java.

Friend Jerry asks how I would code the following in NetRexx.
Well, the above quoted loop forever looks good to me, but I'm
rusty as admitted.

>  public void run() {
>  while (true)
>  count++;
>  }

To me the above is a quick and dirty way to stress your JVM and
OS and find out if it's ever going to fail.  If this code doesn't
kill the process (or starve all the other OS threads till they die
and the OS needs rebooting), well maybe nothing will.  ;)

I don't doubt that someone at Sun may have written this little
counter and distributed it, but the little summary of "why we
deprecated stop() and suspend()" on Sun's site does give a good
clue as to how one should code something like this in the future:

private boolean stopFlag = false;
public void run() {
   int count = 1;
   while( true ) {
      count++;
      if( count % 1000 == 0 && stopFlag )
         return;
   }
}

A method has to be provided somewhere that will change this
thread's stopFlag value to true.  That's what they suggest we
do rather than use stop().  Hope that helps.

- Tony Dahlman  

Surgery, Surgeons and You <http://www.jps.net/adahlman/>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unsubscribe from this mailing list ( ibm-netrexx ), please send a note to
[hidden email]
with the following message in the body of the note
unsubscribe ibm-netrexx <e-mail address>

Reply | Threaded
Open this post in threaded view
|

Re: Bug, bug... who's got the bug?

mcbrides
>Hi all -
>
>Jerry wrote:
>> method run() public
>>
>> loop forever
>>    count = count + 1
>>    end
>
>I apologize.  My NetRexx coding skills have become pretty
>rusty.  I think it's a great implementation for Rexx and the
>ability to write cross-platform scripts that compile to Java
>code is another (and unexpected) big plus for Java.
>
>Friend Jerry asks how I would code the following in NetRexx.
>Well, the above quoted loop forever looks good to me, but I'm
>rusty as admitted.
>
>>  public void run() {
>>  while (true)
>>  count++;
>>  }
>
>To me the above is a quick and dirty way to stress your JVM and
>OS and find out if it's ever going to fail.  If this code doesn't
>kill the process (or starve all the other OS threads till they die
>and the OS needs rebooting), well maybe nothing will.  ;)
>
>I don't doubt that someone at Sun may have written this little
>counter and distributed it, but the little summary of "why we
>deprecated stop() and suspend()" on Sun's site does give a good
>clue as to how one should code something like this in the future:
>
>private boolean stopFlag = false;
>public void run() {
>   int count = 1;
>   while( true ) {
>      count++;
>      if( count % 1000 == 0 && stopFlag )
>         return;
>   }
>}
>
>A method has to be provided somewhere that will change this
>thread's stopFlag value to true.  That's what they suggest we
>do rather than use stop().  Hope that helps.
>

That's an interesting fix. Using a flag to tell the thread when to die is
pretty robust. What I finally figured out about the SUN sample is, it's a
learning tool, eventhough it was passed off as a useful piece of code.

The other way I was able to get the thread to die reliably was placing a very
short sleep() in it and catching InterruptedException like:

  loop forever
    count = count + 1
    catch e = InterruptedException
      return
    end


Presumably (on my part) the exception is tossed when stop() notifies this
thread to die and performs the associated return. So far, in another test
script I wrote, this has reliably terminated the thread. I still find it a
bit unusual that this has popped up as a place where a work-a-round is needed.

Anyway, thanks Dr.Dahlman, for your insight and posting. Working with flags
is probably the better choice as it doesn't leave anything up to the
system to decide (ie. when the thread dies, etc.)

Thanks,

--

/--------------------\
| Jerry McBride      |
| [hidden email] |
\--------------------/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unsubscribe from this mailing list ( ibm-netrexx ), please send a note to
[hidden email]
with the following message in the body of the note
unsubscribe ibm-netrexx <e-mail address>