[squeak-dev] Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Louis LaBrunda
Hi Andreas,

I'm sorry to be resurrecting this thread but my mind often thinks about these
things while trying to get to sleep.  Anyway I hope my suggestions will be of
value.

I am presenting two similar suggestions.  They both accept your desire to have
the new process (or at least the block of the new process) wait to run until
after the calling process can run and save the result of the #fork message.

The first is closest to your suggestion.  Instead of a helper process it wraps
the block being forked in a block that delays running of the forked block until
there are no processes ready to run for the same priority.  I think this is
equivalent to the helper process of a lower priority waiting to run.

The second suggestion also wraps the block being forked in a block that delays
running of the forked block but does so by pushing itself to the back of the
ready to run list for its priority twice.  This should be enough to insure the
calling process has run and saved the result of the #fork message.

I'm not looking for any kind of a fight/trouble, I just thought these might be
an interesting alternative.

Lou

"Suggestion 1 from Lou"
BlockContext>>forkAt: priority
        "Create and schedule a Process running the code in the receiver
                at the given priority. Answer the newly created process."
        | forkedProcess helperBlock |

        helperBlock := [
                [(Processor waitingProcessesAt: priority) notEmpty] whileTrue: [Processor
yield].
                self value.
        ].
        forkedProcess := Process forContext: helperBlock priority: priority.
        ^forkedProcess resume.


"Suggestion 2 from Lou"
BlockContext>>forkAt: priority
        "Create and schedule a Process running the code in the receiver
                at the given priority. Answer the newly created process."
        | forkedProcess helperBlock |

        helperBlock := [
                Processor yield.
                Processor yield.
                self value.
        ].
        forkedProcess := Process forContext: helperBlock priority: priority.
        ^forkedProcess resume.



"Suggestion from Andreas"
BlockContext>>forkAt: priority
   "Create and schedule a Process running the code in the receiver
   at the given priority. Answer the newly created process."
   | forkedProcess helperProcess |

   forkedProcess := self newProcess.
   forkedProcess priority: priority.
   priority = Processor activePriority ifTrue:[
     helperProcess := [forkedProcess resume] newProcess.
     helperProcess priority: priority-1.
     helperProcess resume.
   ] ifFalse:[
     forkedProcess resume
   ].

"Original code"
BlockContext>>forkAt: priority
        "Create and schedule a Process running the code in the receiver
                at the given priority. Answer the newly created process."

        | forkedProcess |
        forkedProcess := self newProcess.
        forkedProcess priority: priority.
        ^ forkedProcess resume
-----------------------------------------------------------
Louis LaBrunda
Keystone Software Corp.
SkypeMe callto://PhotonDemon
mailto:[hidden email] http://www.Keystone-Software.com


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Igor Stasenko
Allow me to add my suggestion, which i hope will let you sleep at nights :)

  BlockContext>>forkAt: priority
         "Create and schedule a Process running the code in the receiver
                 at the given priority. Answer nil."

         | forkedProcess |
         forkedProcess := self newProcess.
         forkedProcess priority: priority.
         forkedProcess resume.
         ^ nil

  BlockContext>>fork
        "Create and schedule a Process running the code in the receiver."
        self newProcess resume.
        ^ nil

These changes will stop forks from being used in wrong manner and
effectively eliminate the problem of "letting fork initiator process
to run little bit more to assign returned value anywhere".

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Igor Stasenko
Oh.. and for those, who may wants use new process instance:

 BlockContext>>forkAfterInitWith: aBlock
  | proc |
  proc := self newProcess.
  aBlock value: proc.
  proc resume.
  ^ nil
---
so, you can write:

[ ....] forkAfterInitWith: [:process | process priority: 100. process
name: 'my forked process' ].


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Paolo Bonzini-2
In reply to this post by Igor Stasenko

>   BlockContext>>fork
> "Create and schedule a Process running the code in the receiver."
> self newProcess resume.
>         ^ nil
>
> These changes will stop forks from being used in wrong manner and
> effectively eliminate the problem of "letting fork initiator process
> to run little bit more to assign returned value anywhere".

I sort of agree (at least on the intent, of course this will break
code).  However, I will point out that problematic uses are only those
who use the #fork return value in a different, already running process.

For example, this code is tricky but not racy, because the second
process isn't started until delayProcess is assigned:

     delayProcess := [
        (Delay forMilliseconds: msec) wait.
         sema signal.
         Processor activeProcess suspend ] fork ].

     [[aBlock value] ensure: [delayProcess terminate. sema signal]] fork.
     sema wait.

but with the sort-of-proposed change to #fork the user could be tempted
to write it like this:

     [
        delayProcess := Processor activeProcess.
        (Delay forMilliseconds: msec) wait.
         sema signal.
         Processor activeProcess suspend ] fork ].

     [[aBlock value] ensure: [delayProcess terminate. sema signal]] fork.
     sema wait.

and the latter *is* racy.

Paolo

Reply | Threaded
Open this post in threaded view
|

RE: [squeak-dev] Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Gary Chambers-4
In reply to this post by Louis LaBrunda
Of course, #1 may never run the context if there is a process that only
tields and doesn't wait (via delay or semaphore)...

[[true] whileTrue: [Processor yield]] fork.
[(Processor waitingProcessesAt: Processor activeProcess priority) notEmpty]
whileTrue: [Processor
yield]. self inform: 'waiting ends'

:-)
Gary


>
> Lou
>
> "Suggestion 1 from Lou"
> BlockContext>>forkAt: priority
> "Create and schedule a Process running the code in the receiver
> at the given priority. Answer the newly created process."
> | forkedProcess helperBlock |
>
> helperBlock := [
> [(Processor waitingProcessesAt: priority) notEmpty]
> whileTrue: [Processor
> yield].
> self value.
> ].
> forkedProcess := Process forContext: helperBlock priority:
> priority.
> ^forkedProcess resume.
>
> >


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Igor Stasenko
In reply to this post by Paolo Bonzini-2
On 03/03/2008, Paolo Bonzini <[hidden email]> wrote:

>
>  >   BlockContext>>fork
>  >       "Create and schedule a Process running the code in the receiver."
>  >       self newProcess resume.
>  >         ^ nil
>  >
>  > These changes will stop forks from being used in wrong manner and
>  > effectively eliminate the problem of "letting fork initiator process
>  > to run little bit more to assign returned value anywhere".
>
>
> I sort of agree (at least on the intent, of course this will break
>  code).  However, I will point out that problematic uses are only those
>  who use the #fork return value in a different, already running process.
>
>  For example, this code is tricky but not racy, because the second
>  process isn't started until delayProcess is assigned:
>
>      delayProcess := [
>         (Delay forMilliseconds: msec) wait.
>          sema signal.
>          Processor activeProcess suspend ] fork ].
>
>      [[aBlock value] ensure: [delayProcess terminate. sema signal]] fork.
>      sema wait.
>
>  but with the sort-of-proposed change to #fork the user could be tempted
>  to write it like this:
>
>      [
>         delayProcess := Processor activeProcess.
>         (Delay forMilliseconds: msec) wait.
>          sema signal.
>          Processor activeProcess suspend ] fork ].
>
>      [[aBlock value] ensure: [delayProcess terminate. sema signal]] fork.
>      sema wait.
>
>  and the latter *is* racy.
>

In this case, i would tell people to read something about Concurrent
Programming before try any coding.

Oh, i giving up. All these patches failing into category: 'selling 2
wheeled bike with 3rd wheel mounted for safety'.
There is little you can do to help people writing good concurrent code
by providing such patches which hiding problems under the hood.
Programmer is not a baby who needs to wear Pampers.

>
>  Paolo
>
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Igor Stasenko
Then, maybe we should go another way,
by modifying compiler and if it finds selectors #fork, #forkAt: used
in code, then
it shows a big red warning which says:
- this method using forks, please check your code twice against
concurrency issues before submitting code. Presse 'yes' to continue

and after user pressing 'yes', shows another:

- are you sure you still want to accept code which using forks? Press
'yes' to not accept this code.

:)

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Bert Freudenberg

On Mar 3, 2008, at 11:53 , Igor Stasenko wrote:

> Then, maybe we should go another way,
> by modifying compiler and if it finds selectors #fork, #forkAt: used
> in code, then
> it shows a big red warning which says:
> - this method using forks, please check your code twice against
> concurrency issues before submitting code. Presse 'yes' to continue
>
> and after user pressing 'yes', shows another:
>
> - are you sure you still want to accept code which using forks? Press
> 'yes' to not accept this code.
>
> :)

Nah, it should simply analyze the code and fix up any potential bugs.

- Bert -



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Klaus D. Witzel
On Mon, 03 Mar 2008 12:12:20 +0100, Bert Freudenberg wrote:

>
> On Mar 3, 2008, at 11:53 , Igor Stasenko wrote:
>
>> Then, maybe we should go another way,
>> by modifying compiler and if it finds selectors #fork, #forkAt: used
>> in code, then
>> it shows a big red warning which says:
>> - this method using forks, please check your code twice against
>> concurrency issues before submitting code. Presse 'yes' to continue
>>
>> and after user pressing 'yes', shows another:
>>
>> - are you sure you still want to accept code which using forks? Press
>> 'yes' to not accept this code.
>>
>> :)
>
> Nah, it should simply analyze the code and fix up any potential bugs.

And while it's at it, also solve all the performance problems in the code.

/Klaus

> - Bert -
>
>
>
>



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Paolo Bonzini-2
In reply to this post by Igor Stasenko

> In this case, i would tell people to read something about Concurrent
> Programming before try any coding.

Yes, and that's why I was against Andreas' patch in the first place. :-(

Paolo

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Louis LaBrunda
In reply to this post by Igor Stasenko
Hi Igor,

On Sun, 2 Mar 2008 21:09:59 +0200, "Igor Stasenko" <[hidden email]> wrote:

>snip
>These changes will stop forks from being used in wrong manner and
>effectively eliminate the problem of "letting fork initiator process
>to run little bit more to assign returned value anywhere".

I agree in part.  I actually think fork shouldn't be changed at all.  There is
nothing wrong with fork returning the resulting process.  The calling process
and the new process shouldn't assume anything about the other having been run or
not.

I only came up with my alternative because I couldn't sleep.  I wasn't losing
sleeping trying to fine an alternative.

Lou
-----------------------------------------------------------
Louis LaBrunda
Keystone Software Corp.
SkypeMe callto://PhotonDemon
mailto:[hidden email] http://www.Keystone-Software.com


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Alternate BlockContext>>forkAt: for Andreas, was #fork and deterministic resumption of the resulting process

Louis LaBrunda
In reply to this post by Gary Chambers-4
Hi Gary,

On Mon, 3 Mar 2008 10:17:53 -0000, "Gary Chambers" <[hidden email]>
wrote:

>Of course, #1 may never run the context if there is a process that only
>tields and doesn't wait (via delay or semaphore)...
>
>[[true] whileTrue: [Processor yield]] fork.
>[(Processor waitingProcessesAt: Processor activeProcess priority) notEmpty]
>whileTrue: [Processor
>yield]. self inform: 'waiting ends'
>
>:-)
>Gary

Yes, and I think Andreas' solution would suffer the same problem.  And would any
code with a lower priority ever run.

Lou
-----------------------------------------------------------
Louis LaBrunda
Keystone Software Corp.
SkypeMe callto://PhotonDemon
mailto:[hidden email] http://www.Keystone-Software.com