You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Cristian Lorenzetto <cr...@gmail.com> on 2018/01/19 19:26:58 UTC

[javaflow] - how to use continuation in JNI boundary

Hi

I have a similar scenario

public static final class MyCoroutine implements Runnable {

     Continuation c;
     MyCoroutine(){
       c=Continuation.startWith(this);
     }

    @Override
    public void run() {
       native_func(c, new NativeCallback(){  // inside JNI native_func
Continuation.suspend(); is executed before to call callback.

     public static void callback(){
           Continuation.continueWith(MyCoroutine.this);

    }


   });
}

}

could it work?

I might find a way for calling a native method making a stuff and when is
completed, it calls  a callback( NativeCallback) reactiving the coroutine.

Is there a way for doing it?

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
I don't want to discourage you from contributing but...
as also descripted in the Loom proposal already suggests - it's much more
than just patching the Instrumenter.
If you want to re-use the threads you also need to add some kind of pooling
and scheduling mechanism.

On Sun, Jan 21, 2018 at 2:00 AM, Cristian Lorenzetto <
cristian.lorenzetto@gmail.com> wrote:

> I read now Loom project is thinking to do exactly what i proposed. But when
> it will be available? uhmmm i think i could require years...
> I dont know , maybe i could patch the instrumenter
>
> 2018-01-21 1:21 GMT+01:00 Torsten Curdt <tc...@vafer.org>:
>
> > This does not remove the restriction on the synchronization - that still
> > exists.
> > The thread could do something else during the wait - but that's another
> > story.
> >
> > There just is not automatic suspend on wait.
> > And it begs the question how such a thing would/should look like.
> >
> > I am not saying this isn't something that could be interesting to
> > investigate - but this is just not what javaflow is.
> > The current javaflow implementation is about state storing and restoring
> -
> > not scheduling and pooling.
> >
> > While you could improve thread usage by implementing thread re-use during
> > wait, the big problem will still always be the synchronized code.
> > So it really feels like you are trying to solve a problem from the wrong
> > end.
> >
> > Anyway - my 2 cents.
> > Take them or leave 'em ;)
> >
> > On Sun, Jan 21, 2018 at 12:36 AM, Cristian Lorenzetto <
> > cristian.lorenzetto@gmail.com> wrote:
> >
> > > It is absolutely not true. If a coroutine  execute
> > >
> > > synchonized(lock){ lock.wait() }
> > >
> > > the lock.wait blocks the thread. Why i have to block the thread if
> thread
> > > can running other corotuines in the while?
> > > lock.wait must supend the coroutine and resuming another coroutine
> > >
> > > 2018-01-21 0:23 GMT+01:00 Torsten Curdt <tc...@vafer.org>:
> > >
> > > > I am sorry but I must be missing something here.
> > > >
> > > > The code uses synchronization blocks and mutexes to explicitly make
> > sure
> > > > threads don't interfere which each other.
> > > > This restriction will be there because of resource sharing and the
> java
> > > > memory model.
> > > > Instrumenting wait/notify cannot magically remove that restriction.
> > > >
> > > > Based on queuing theory you can move your bottleneck to your mutexes
> -
> > > but
> > > > that's about it.
> > > >
> > >
> >
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
I read now Loom project is thinking to do exactly what i proposed. But when
it will be available? uhmmm i think i could require years...
I dont know , maybe i could patch the instrumenter

2018-01-21 1:21 GMT+01:00 Torsten Curdt <tc...@vafer.org>:

> This does not remove the restriction on the synchronization - that still
> exists.
> The thread could do something else during the wait - but that's another
> story.
>
> There just is not automatic suspend on wait.
> And it begs the question how such a thing would/should look like.
>
> I am not saying this isn't something that could be interesting to
> investigate - but this is just not what javaflow is.
> The current javaflow implementation is about state storing and restoring -
> not scheduling and pooling.
>
> While you could improve thread usage by implementing thread re-use during
> wait, the big problem will still always be the synchronized code.
> So it really feels like you are trying to solve a problem from the wrong
> end.
>
> Anyway - my 2 cents.
> Take them or leave 'em ;)
>
> On Sun, Jan 21, 2018 at 12:36 AM, Cristian Lorenzetto <
> cristian.lorenzetto@gmail.com> wrote:
>
> > It is absolutely not true. If a coroutine  execute
> >
> > synchonized(lock){ lock.wait() }
> >
> > the lock.wait blocks the thread. Why i have to block the thread if thread
> > can running other corotuines in the while?
> > lock.wait must supend the coroutine and resuming another coroutine
> >
> > 2018-01-21 0:23 GMT+01:00 Torsten Curdt <tc...@vafer.org>:
> >
> > > I am sorry but I must be missing something here.
> > >
> > > The code uses synchronization blocks and mutexes to explicitly make
> sure
> > > threads don't interfere which each other.
> > > This restriction will be there because of resource sharing and the java
> > > memory model.
> > > Instrumenting wait/notify cannot magically remove that restriction.
> > >
> > > Based on queuing theory you can move your bottleneck to your mutexes -
> > but
> > > that's about it.
> > >
> >
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
This does not remove the restriction on the synchronization - that still
exists.
The thread could do something else during the wait - but that's another
story.

There just is not automatic suspend on wait.
And it begs the question how such a thing would/should look like.

I am not saying this isn't something that could be interesting to
investigate - but this is just not what javaflow is.
The current javaflow implementation is about state storing and restoring -
not scheduling and pooling.

While you could improve thread usage by implementing thread re-use during
wait, the big problem will still always be the synchronized code.
So it really feels like you are trying to solve a problem from the wrong
end.

Anyway - my 2 cents.
Take them or leave 'em ;)

On Sun, Jan 21, 2018 at 12:36 AM, Cristian Lorenzetto <
cristian.lorenzetto@gmail.com> wrote:

> It is absolutely not true. If a coroutine  execute
>
> synchonized(lock){ lock.wait() }
>
> the lock.wait blocks the thread. Why i have to block the thread if thread
> can running other corotuines in the while?
> lock.wait must supend the coroutine and resuming another coroutine
>
> 2018-01-21 0:23 GMT+01:00 Torsten Curdt <tc...@vafer.org>:
>
> > I am sorry but I must be missing something here.
> >
> > The code uses synchronization blocks and mutexes to explicitly make sure
> > threads don't interfere which each other.
> > This restriction will be there because of resource sharing and the java
> > memory model.
> > Instrumenting wait/notify cannot magically remove that restriction.
> >
> > Based on queuing theory you can move your bottleneck to your mutexes -
> but
> > that's about it.
> >
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
It is absolutely not true. If a coroutine  execute

synchonized(lock){ lock.wait() }

the lock.wait blocks the thread. Why i have to block the thread if thread
can running other corotuines in the while?
lock.wait must supend the coroutine and resuming another coroutine

2018-01-21 0:23 GMT+01:00 Torsten Curdt <tc...@vafer.org>:

> I am sorry but I must be missing something here.
>
> The code uses synchronization blocks and mutexes to explicitly make sure
> threads don't interfere which each other.
> This restriction will be there because of resource sharing and the java
> memory model.
> Instrumenting wait/notify cannot magically remove that restriction.
>
> Based on queuing theory you can move your bottleneck to your mutexes - but
> that's about it.
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
I am sorry but I must be missing something here.

The code uses synchronization blocks and mutexes to explicitly make sure
threads don't interfere which each other.
This restriction will be there because of resource sharing and the java
memory model.
Instrumenting wait/notify cannot magically remove that restriction.

Based on queuing theory you can move your bottleneck to your mutexes - but
that's about it.

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
synchonized blocks are not used for coroutines but the code inside the
coroutine uses mutexes... so synchonized,wait/notify are present.

For this reason i i want instrument wait/notify ... for replacing normal
mutex parking the thread with a mutex suspending the coroutine

2018-01-20 23:24 GMT+01:00 Cristian Lorenzetto <
cristian.lorenzetto@gmail.com>:

> "unless your code
> requires it". Yes my code contains synchonized blocks. I used also
> external libraries using other synchonized blocks. So i can replace
> synchonized blocks manually.
>
> The coroutine runs code using mutex and shared resources.
>
> 2018-01-20 23:17 GMT+01:00 Torsten Curdt <tc...@vafer.org>:
>
>> > this is a problem for me.
>> >
>>
>> I don't see the problem yet
>>
>>
>>
>> > My idea is to use many coroutines instead to use many threads because
>> it is
>> > more scalable.
>>
>>
>> *nod*
>>
>>
>> Consider i realize a scheduler in which i can push many coroutines.
>> > Pratically it is a coroutines pool inside the same thread.
>> >
>>
>> Yes, that is possible. The continuations are not bound to threads.
>>
>>
>>
>> > When a corotuines is blocked by a wait() instruction it is not
>> necessary to
>> > block the thread but it is sufficient to suspend it.
>> > When a corotuine is suspended , it is taken another  coroutine ready to
>> be
>> > resumed. In this way the thread is never blocked ... and the global
>> > performance will be very hight.
>> >
>> > For this reason is important to instrument synchronized blocks.
>> >
>>
>> Sorry, but I don't see your point yet.
>>
>> It's been a while since I wrote that library but...
>> Frankly speaking I don't see the need for synchronization.
>> The state is handled per thread and it then creates a new continuation.
>> There is no mutation an no need for synchronization - unless your code
>> requires it.
>>
>
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
"unless your code
requires it". Yes my code contains synchonized blocks. I used also external
libraries using other synchonized blocks. So i can replace synchonized
blocks manually.

The coroutine runs code using mutex and shared resources.

2018-01-20 23:17 GMT+01:00 Torsten Curdt <tc...@vafer.org>:

> > this is a problem for me.
> >
>
> I don't see the problem yet
>
>
>
> > My idea is to use many coroutines instead to use many threads because it
> is
> > more scalable.
>
>
> *nod*
>
>
> Consider i realize a scheduler in which i can push many coroutines.
> > Pratically it is a coroutines pool inside the same thread.
> >
>
> Yes, that is possible. The continuations are not bound to threads.
>
>
>
> > When a corotuines is blocked by a wait() instruction it is not necessary
> to
> > block the thread but it is sufficient to suspend it.
> > When a corotuine is suspended , it is taken another  coroutine ready to
> be
> > resumed. In this way the thread is never blocked ... and the global
> > performance will be very hight.
> >
> > For this reason is important to instrument synchronized blocks.
> >
>
> Sorry, but I don't see your point yet.
>
> It's been a while since I wrote that library but...
> Frankly speaking I don't see the need for synchronization.
> The state is handled per thread and it then creates a new continuation.
> There is no mutation an no need for synchronization - unless your code
> requires it.
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
> this is a problem for me.
>

I don't see the problem yet



> My idea is to use many coroutines instead to use many threads because it is
> more scalable.


*nod*


Consider i realize a scheduler in which i can push many coroutines.
> Pratically it is a coroutines pool inside the same thread.
>

Yes, that is possible. The continuations are not bound to threads.



> When a corotuines is blocked by a wait() instruction it is not necessary to
> block the thread but it is sufficient to suspend it.
> When a corotuine is suspended , it is taken another  coroutine ready to be
> resumed. In this way the thread is never blocked ... and the global
> performance will be very hight.
>
> For this reason is important to instrument synchronized blocks.
>

Sorry, but I don't see your point yet.

It's been a while since I wrote that library but...
Frankly speaking I don't see the need for synchronization.
The state is handled per thread and it then creates a new continuation.
There is no mutation an no need for synchronization - unless your code
requires it.

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
this is a problem for me.

My idea is to use many coroutines instead to use many threads because it is
more scalable.
Consider i realize a scheduler in which i can push many coroutines.
Pratically it is a coroutines pool inside the same thread.

When a corotuines is blocked by a wait() instruction it is not necessary to
block the thread but it is sufficient to suspend it.
When a corotuine is suspended , it is taken another  coroutine ready to be
resumed. In this way the thread is never blocked ... and the global
performance will be very hight.

For this reason is important to instrument synchronized blocks.









2018-01-20 19:51 GMT+01:00 Torsten Curdt <tc...@vafer.org>:

> > because the stack when is suspended is out from native func.
> > instead if i call suspend inside a JNI c++ class the stack is not visible
> > from java so probably javaflow dont work.
> >
>
> The short answer to that question is "yes".
>
>
>
> > I have another different question:
> > run(){
> > while(!stream.eof()){
> >    data=read(stream);
> >   process(data);
> > }.
> >
> > stream is synchonized internally waiting until data is not empty.
> >
>
> How is that example even related to javaflow?
> What's the goal here?
>
>
> My question is: normally in synchonized blocks the thread is blocked until
> > notify but inside a coroutine the class is instrumented for not blocking
> > the thread but just for suspending the coroutine until notify?
> >
>
> That doesn't sound quite right.
> While it is true that calls to a synchronized function will have to wait
> for a lock on "this",
> I would not use terms "synchronized" and "blocking" like that.
>
> Maybe let's try give a birds eye view on how javaflow works.
>
> 1. On suspend the function will exit but also store state information in
> the Continuation object.
> 2. On resume the library will call the function again, but it will restore
> the state and jump to the position after it was suspended.
>
> The synchronization characteristics should not be affected by that.
>
> cheers,
> Torsten
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
> because the stack when is suspended is out from native func.
> instead if i call suspend inside a JNI c++ class the stack is not visible
> from java so probably javaflow dont work.
>

The short answer to that question is "yes".



> I have another different question:
> run(){
> while(!stream.eof()){
>    data=read(stream);
>   process(data);
> }.
>
> stream is synchonized internally waiting until data is not empty.
>

How is that example even related to javaflow?
What's the goal here?


My question is: normally in synchonized blocks the thread is blocked until
> notify but inside a coroutine the class is instrumented for not blocking
> the thread but just for suspending the coroutine until notify?
>

That doesn't sound quite right.
While it is true that calls to a synchronized function will have to wait
for a lock on "this",
I would not use terms "synchronized" and "blocking" like that.

Maybe let's try give a birds eye view on how javaflow works.

1. On suspend the function will exit but also store state information in
the Continuation object.
2. On resume the library will call the function again, but it will restore
the state and jump to the position after it was suspended.

The synchronization characteristics should not be affected by that.

cheers,
Torsten

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Cristian Lorenzetto <cr...@gmail.com>.
What i think to understand is :

Coroutine can be suspended in a block like run() {
    native_func();
    Continuation.suspend();

  }
because the stack when is suspended is out from native func.
instead if i call suspend inside a JNI c++ class the stack is not visible
from java so probably javaflow dont work.

I have another different question:
run(){
while(!stream.eof()){
   data=read(stream);
  process(data);
}.

stream is synchonized internally waiting until data is not empty.

My question is: normally in synchonized blocks the thread is blocked until
notify but inside a coroutine the class is instrumented for not blocking
the thread but just for suspending the coroutine until notify?












2018-01-20 18:12 GMT+01:00 Torsten Curdt <tc...@vafer.org>:

> Hey Cristian,
>
> you have to think of javaflow continuations of having multiple ways of
> running through the "run" function with different entry and exit points.
>
> What should/will work is:
>
>   run() {
>     native_func();
>     Continuation.suspend();
>     native_func();
>     Continuation.suspend();
>   }
>
> I am not quite sure what you are trying to do with your setup. Why
> callbacks in a continuation world?
> Keep in mind that the native code is not instrumented.
>
> cheers,
> Torsten
>

Re: [javaflow] - how to use continuation in JNI boundary

Posted by Torsten Curdt <tc...@vafer.org>.
Hey Cristian,

you have to think of javaflow continuations of having multiple ways of
running through the "run" function with different entry and exit points.

What should/will work is:

  run() {
    native_func();
    Continuation.suspend();
    native_func();
    Continuation.suspend();
  }

I am not quite sure what you are trying to do with your setup. Why
callbacks in a continuation world?
Keep in mind that the native code is not instrumented.

cheers,
Torsten