mIRC Home    About    Download    Register    News    Help

Print Thread
#217217 05/01/10 04:38 AM
Joined: Aug 2006
Posts: 183
T
Thrull Offline OP
Vogon poet
OP Offline
Vogon poet
T
Joined: Aug 2006
Posts: 183
Hello,

The timer function doesn't seem to always keep track of what order timers were called. In this code...

Code:
alias timet {
  var %j -1
  while %j < 3 {
    .timer 1 %j echo -a %j
    inc %j
  }
}


...one would expect the output to be -1, 0, 1 then 2. However, it always gives the output in this order: 0, -1, 1, 2. Now, I understand that giving /timer a negative number might throw an exception, so I tested that as well using the following code.

Code:
alias timet {
  var %j -1
  while %j < 3 {
if %j < 0 { var %k 0 }
else { var %k = %j }
    .timer 1 %k echo -a %j -- %k
    inc %j
  }
}


It still produces the same erroneous output.

However, if one uses the -h switch the problem seems to vanish. I can't imagine this is intended behavior, though.


Yar
Thrull #217219 05/01/10 10:14 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
It is. Timers trigger in the order that the Windows API decides they do. The -h switch (highres) makes Windows API think more carefully about order, which matters when the timers are all triggered within the same millisecond (usually the case for a while loop).

In short, it's out of mIRC's hands (mIRC is likely even issuing the timer commands in the correct order). If you care about timer order, you want a highres timer.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Thrull #217226 05/01/10 03:16 PM
Joined: Dec 2002
Posts: 2,033
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Dec 2002
Posts: 2,033

Try using the -d switch.

From versions.txt

28/07/2006 - mIRC v6.2

Changes:
..
25. Added /timer -d switch, ensures that a timer and any subsequent timers using the -d switch are triggered in that order.

Last edited by RoCk; 05/01/10 03:21 PM.
RoCk #217232 05/01/10 04:16 PM
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
A negative delay put aside,I never got the d-switch working for that.
E.g.:
Code:
//.timer -d 1 0 echo -a 1 | .timer -d 1 0 echo -a 2 | .timer -d 1 0 echo -a 3
sometimes resulted in "1 2 3" but most times in "2 1 3" on my machine...

I thus did:
Code:
; /timertest [h|d]
alias timertest {
  var %a = 1, %b = 1, %s = $left($1,1)
  echo -ag * starting 8 timers (4x 0s, 4x 1s) with $iif((%s isin hd),the $v1,no) switch...
  while (%a <= 4) {
    .timer $iif((%s isin hd),- $+ $v1) 1 0 echo -ag delay 0 : $ord(%a)
    inc %a
  }  
  while (%b <= 4) {
    .timer $iif((%s isin hd),- $+ $v1) 1 $iif((%s == h),1000,1) echo -ag delay 1 : $ord(%b)
    inc %b
  }
}

/timertest
* starting 8 timers (4x 0s, 4x 1s) with no switch...
delay 0 : 4th
delay 0 : 3rd
delay 0 : 2nd
delay 0 : 1st
delay 1 : 1st
delay 1 : 2nd
delay 1 : 3rd
delay 1 : 4th

/timertest d
* starting 8 timers (4x 0s, 4x 1s) with the d switch...
delay 0 : 4th
delay 0 : 3rd
delay 0 : 2nd
delay 0 : 1st
delay 1 : 1st
delay 1 : 2nd
delay 1 : 3rd
delay 1 : 4th

/timertest h
* starting 8 timers (4x 0s, 4x 1s) with the h switch...
delay 0 : 1st
delay 0 : 2nd
delay 0 : 3rd
delay 0 : 4th
delay 1 : 1st
delay 1 : 2nd
delay 1 : 3rd
delay 1 : 4th

Now I wonder what -d is made for... I tested as well with named timers and/or timers that will fire at a certain [time] value...
Code:
alias timertest2 {
  var %s = $iif(($1 == d),-d), %t = $asctime($calc($ctime +60),HH:nn)
  echo -ag * starting 6 timers $iif(%s,with the $v1 switch) (3 fire at %t $+ :00, 3 fire at %t $+ :01)...

  .timerB %s %t 1 0 echo -ag 1st
  .timerA %s %t 1 0 echo -ag 2nd
  .timerC %s %t 1 0 echo -ag 3rd

  .timerZ %s %t 1 1 echo -ag 1st
  .timerX %s %t 1 1 echo -ag 2nd
  .timerY %s %t 1 1 echo -ag 3rd
}

/timertest2
* starting 6 timers (3 fire at 17:10:00, 3 fire at 17:10:01)...
3rd
2nd
1st
2nd
3rd
1st

/timertest2 d
* starting 6 timers with the -d switch (3 fire at 17:11:00, 3 fire at 17:11:01)...
3rd
2nd
1st
2nd
3rd
1st

confused
Edit: the -d switch is taken into account in the list of timers (/timer). I don't see any effect beyond that though.

Last edited by Horstl; 05/01/10 04:22 PM.
Horstl #217235 05/01/10 05:15 PM
Joined: Dec 2002
Posts: 2,033
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Dec 2002
Posts: 2,033

I got 2 1 3 everytime as well, until I removed the silencers in your test and the outputs changed to 2 3 1 everytime. Strange.

RoCk #217245 05/01/10 11:42 PM
Joined: Aug 2006
Posts: 183
T
Thrull Offline OP
Vogon poet
OP Offline
Vogon poet
T
Joined: Aug 2006
Posts: 183
I had tried the -d switch as well, but it didn't work any better for me.


Yar
Thrull #217246 06/01/10 12:00 AM
Joined: Jan 2010
Posts: 11
E
Pikka bird
Offline
Pikka bird
E
Joined: Jan 2010
Posts: 11
argv0 was on the right track about the API. Event driven multi-tasking environments give processes priorities. Addressing an API timer event as high priority will yield more expected results with the cost of processing speed.

On a side note Thrull, on my machine with Win 7, your code without the -h worked fine every time. All numbers in order.

extremity #217247 06/01/10 12:49 AM
Joined: Aug 2006
Posts: 183
T
Thrull Offline OP
Vogon poet
OP Offline
Vogon poet
T
Joined: Aug 2006
Posts: 183
Well, I'm not going to get Win7 to solve the issue. smile Even if Argv0 is correct about the API issue (and I don't doubt he is), it'd be nice if the timers all functioned the same way on all version of Windows. Perhaps it really can't be done, I don't know enough about Windows API and the internals of Mirc.


Yar
Thrull #217250 06/01/10 02:53 AM
Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
Regretfully, timers are not 100% accurate.
regular timers, which are set to the second can (and do) actually trigger with up to a 1 second variance.

This can be reduced by using a millisecond timer.

I seem to recall this situation being reported earlier, but I don't recall when... Sorry.

Thus an intermediate solution maybe to use the -m with or without the c switch, which will keep the timer even more accurate.

Thrull #217251 06/01/10 02:58 AM
Joined: Jan 2010
Posts: 11
E
Pikka bird
Offline
Pikka bird
E
Joined: Jan 2010
Posts: 11
I choose to write recursive routines using timers instead. (Even though it is bad mIRC mojo).

But that's just me.

Code:
alias testt {
  var %i $1
  if (%i > 3) { halt }
  echo -a Timer iteration: %i
  inc %i
  .timer -m 1 1 testt %i
}

extremity #217255 06/01/10 05:12 AM
Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
As someone said to me once : "If it ain't broke, don't fix it"

Thrull #217283 07/01/10 02:47 AM
Joined: Jan 2010
Posts: 4
X
Self-satisified door
Offline
Self-satisified door
X
Joined: Jan 2010
Posts: 4
i know in some programming languages when you want to order numbers it will order them in a similar matter as to what you've shown here

Quote:
0, -1, 1, 2


or for another example this sequence of numbers

0,1,2,3,10,11,22,23,34,35
would be ordered as
0,1,10,11,2,22,23,3,34,35

in mySQL this problem occurs when you are assigning the numbers as asc, or chr values instead of int's I know you cant really control how mIRC stores the data in this case but im thinking this could be what's causing this issue as the pattern you've displayed seems to be ordered in a similar fashion if you see what im getting at. I dont know if this will help you directly but perhaps if this is the same issue in mIRC in a future version they can through in a flag to indicate your timer name is an integer and not of type char. Hope this might shed some light.

Thrull #217308 07/01/10 11:45 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
@ Thrull:

You don't have to "believe" me, you just need to read the Timers API:

Quote:
The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions post this message only when no other higher-priority messages are in the thread's message queue.


http://msdn.microsoft.com/en-us/library/ms644902%28VS.85%29.aspx

This means things like keyboard events, mouse events and probably many others can all make a timer run slow.

And yes, /timer *is* implemented via WM_TIMER.

But more pertinent: timers do function the same on all versions of windows. The problem here is that your expectation is not reasonable. /timer is neither expected to trigger in order (-d triggers them in order on mIRC's end, not Windows') nor give you "exact" timings. It's well known that a "1 second" timer will never trigger in exactly 1000ms. In fact, the actual timing could be anywhere from 500ms to 1500ms, given "bug reports" of the past (they weren't actually bugs, of course). With this fact in mind, it's conceivable that 3 timers could easily trigger out of order (timer1 triggers in 1500ms but the others trigger in ~900ms). This is how the Windows API works, and pretty much how any sort of multi-threaded environment (or emulation thereof) will be expected to function. In fact, even the Windows API docs tell you that pretty much nothing is accurate to 1ms by default (it's more like 15ms). That means that if you need to do time-sensitive work, you need to tell the OS; this is what -h is for. Otherwise your timers are approximations and should not be time sensitive.

The fact that on Win7 the numbers order up is irrelevant. You should not be expecting any order without -h.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #217317 08/01/10 05:23 AM
Joined: Aug 2006
Posts: 183
T
Thrull Offline OP
Vogon poet
OP Offline
Vogon poet
T
Joined: Aug 2006
Posts: 183
Point taken.

My only gripe is that the script had been working perfectly for months and all the sudden started to not work properly. I tracked down the source and found it to be this problem.

If it was something that could be easily fixed, then a bug report was worth the time. If not, then I already have a solution and it isn't that big of a deal.

Quote:
The fact that on Win7 the numbers order up is irrelevant. You should not be expecting any order without -h.


Well, given that it worked fine for months, and I saw no reason it shouldn't suddenly stop working probably, my expectations were fair. And given the amount of bug reports that have been posted on it (or similar things involving /timer) Khlaed may well want to add a bit more in the help file to explain away some of the misconceptions.


Yar

Link Copied to Clipboard