Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sleep: and sleepMillis: methods in System #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Hirevo
Copy link

@Hirevo Hirevo commented Jun 17, 2020

When testing System>>#ticks and System>>#time, I was looking for a way to somewhat predictably wait a specific amount of time, regardless of the interpreter's evaluation speed.
Currently the only way to make the interpreter wait is using a busy wait (something like: 1000000 timesRepeat: nil), which is not ideal.
Since thread-sleeping is a commonly available operation, I figured that we could probably expose it to SOM programs to allow them to pause execution efficiently.

So this PR proposes to add the System>>#sleepMillis: primitive, to stop evaluating the program for the given amount of time in milliseconds (the only accepted type of argument would be a positive Integer).
This PR also includes the System>>#sleep: method, which stops the program for the given amount of time in seconds, rather than in milliseconds, and is implemented in terms of System>>#sleepMillis:.

@smarr
Copy link
Member

smarr commented Jun 17, 2020

Hmm, difficult. This seems a single purpose primitive for the moment.

I don't want to outright dismiss it, since such contributions are very valuable, but I'd rather not go through the trouble implementing it for all SOMs. I am not even sure how to do it for JavaScript.

So, perhaps asked differently, is there another important use case for the primitive?

While it's nice to see that you want to bring test coverage up, for the moment, I wonder whether this is a good tradeoff.

For your testing in SOM-rs, you may simply cheat in the interpreter and provide the primitive even though it is not explicitly defined, which could be a good middle ground for the moment.

@smarr smarr added enhancement Improves the implementation with something noteworthy language design This issue requires design decisions labels Jun 17, 2020
@ltratt
Copy link

ltratt commented Jun 17, 2020

You can implement "pause" simply using ticks: you just spin in a while loop. Obviously this is not a very good implementation, but it does at least avoid adding a primitive.

@Hirevo
Copy link
Author

Hirevo commented Jun 18, 2020

I was just proposing this because efficient waiting isn't doable in application code without support from the interpreter, so I was wondering if proposing it would spark interest for this.

If the value of this feature is considered lower compared to the effort needed to implement it in all interpreters, then I am totally fine with dropping this PR (+ I agree that it would be tricky to implement this in JS without rewriting to use async).

As pointed out by @ltratt, there is indeed a better alternative than what I wrote in the original message that I didn't think about, in order to await a specific amount of time predictably, so it is not that bad after all:

Timer = (
  wait: millis = (
    | start |
    start := system ticks / 1000.
    [ system ticks / 1000 - start < millis ] whileTrue: nil.
  )
)

And I can't think of another real use-case yet for the primitive, so yeah, feel free to close the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improves the implementation with something noteworthy language design This issue requires design decisions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants