Announcement

Collapse
No announcement yet.

Sys.getTimer() can be negative

Collapse
X
  • Time
  • Show
Clear All
new posts

  • Sys.getTimer() can be negative

    This isn't so much a bug but rather people should be aware that Sys.getTimer() can return a negative number. It returns a value of type Number, which is a 32 bit signed value. Generally this starts counting at zero when the device is rebooted. After about 25 days, this will wrap and become negative. (2^31)/60/60/24/1000=days.

    I'm just mentioning it because I had a couple bugs where I assumed Sys.getTimer() was always >= 0, not to mention kept getting larger.

    It's the sort of bug that can be really difficult to track down as it appears totally random and not easily reproducible if you aren't aware of it.
    Last edited by Coleman.ConnectIQ; 10-05-2018, 12:35 PM.

  • #2
    I realized that a few months back when my stopwatch app got negative ratings because of weird times being shown . When thinking about it it is obvious that this value must overflow at some point, as 32bit is very limited and we are talking about milliseconds here

    Hopefully in the future the architecture will be migrated to 64 bit, until then this needs to be handled properly by the developer.

    Bye

    Comment


    • #3
      Definitely should be documented.
      An app could convert it it a long (64bit) and handle the negatives which could help some by extending it to about 50 days when it would go back positive.
      My Connect IQ Apps in the Store
      Facebook - Instagram -
      Twitter

      Comment


      • #4
        Thanks for the report. I've created a ticket to confirm that this isn't a bug, then to document whatever is expected here.

        -Coleman

        Comment


        • #5
          As long as we use a fixed-precision type, there will be a limit. If you're calculating the difference between times that are less than 25 days apart this should not be an issue, and simple subtraction should be sufficient. You can keep a rolling counter of the number of milliseconds in a long, or use seconds and milliseconds.

          The documentation already says that the returned type is Lang.Number and Lang.Number is documented to be a 32-bit signed value. I'm not sure how much more documentation is necessary, and if we do it here how many other places we need to mention limitations of the underlying data type.

          Converting to a 64-bit type would give us a *lot* more than 50 days.. every additional bit doubles the range. With a 64-bit counter you'd get more than 250 thousand years.

          Comment


          • #6
            It is an interesting dilemma for documenting. Yes, it should be obvious from the type that this will occur. I was, however, a bit surprised to see how short the rollover interval is when I actually did the math. And as Travis points out, subtraction and then comparing for less than a certain time works. In my case (obviously incorrectly) I was assuming the value zero was less than any value I'd see.

            It could certainly be argued documenting this a bit more clearly than most rollover cases would make sense, given that I suspect most people would just assume a system timer like this would keep growing. And this would be a particularly hard one to reproduce since you have to be in the 25 day window.

            But my main point for starting this thread was that if someone searches for SysTimer() problems, they may find this and get clued into their problem. Good news is that the devices are running long enough now to be hitting this.

            Comment


            • #7
              I also think that a short statement like "IMPORTANT: timer value overflows after 25 days and becomes negative" is something that would help a lot of people to not run into bad reviews for their apps because they missed this fact. In my opinion the argument about documenting an obvious case for 32 bit numbers is invalid, as here this particular number is used to represent a specific use case for a user: how many milliseconds the device is already running. So from that point of view I would surely vote pro documentation in System.getTimer().

              Bye

              Comment


              • #8
                I guess I think the 25 days makes it worthy to note in the doc, as it's something that can easily happen on a device. If it were 250 days, not so much, as I think most devices are restarted in that amount of time. There is a similar thing with Time.now().value(), but that's still years off.

                People see that it's a Number, but as ekutter said, unless you do the math, may not realize what that translates to. A note would help.

                If the VM can see the real value, making the return a long instead of a Number would eliminate this, and I've not thought of a case where that change would impact on existing apps, but could help some. I have a widget that shows "up time", which is just taking the value and displaying it as "DAYS HH:MM:SS" for example.
                My Connect IQ Apps in the Store
                Facebook - Instagram -
                Twitter

                Comment


                • #9
                  I have a feeling people are running into this bug much more than we think. Since one of the first things you do (we've learned over time with computes) when you start having random problems is reboot. In this case that fixes the problem. So people quickly chalk it up to a random one off problem, rather than a real bug to be diagnosed. Not unlike the WebRequest() bug we dealt with a couple months ago.

                  Comment


                  • #10
                    Originally posted by jim_m_58 View Post
                    II've not thought of a case where that change would impact on existing apps, but could help some.
                    Changing the type of a variable or a return to Long or Double has side effects. One issue is that these types are stored in the heap. This means that they take up additional memory and require an additional level of indirection to access the value which can reduce performance. If you are doing arithmetic on the result of that call, the result of the arithmetic would implicitly be of the larger type... it spreads like a virus.

                    We discussed this issue yesterday and we will be making a note in the documentation to say that the timer will wrap after 25-ish days.

                    Comment

                    Working...
                    X