Uptime command
Pages: 1 2
Chris Mahoney (1684) 2165 posts |
Which of course won’t work, because subtracting the monotonic timer won’t accomplish anything useful if it’s already wrapped around… Anyway, I’ve done some more testing and am now declaring that 0.08 is at least as stable as 0.07. It correctly survives a single rollover, at least! I’ve come up with a way of faking a second rollover and will hopefully have time to test that tonight. |
Chris Mahoney (1684) 2165 posts |
And test it [PackMan], I did! My earlier post was poorly worded (or, to put it another way, wrong). PackMan can indeed handle this; PackIt, on the other hand, struggles. PackIt strips the file type off the module and doesn’t allow installation into PreDesk. Fortunately the package format itself doesn’t have these issues. I’ve made and tested a packaged version. It installs the module into PreDesk so that it starts on boot. It also RMLoads it so that it’s immediately available after installation. Does anyone know whether the “Policy Manual” version 0.4 is available somewhere? My package specifies its compatibility as 0.4 and I don’t think I’ve used any features specific to 0.5, but I can’t find the manual to double-check. |
Alan Buckley (167) 232 posts |
As you’ve discovered, PackIt just supports a subset of everything you can do with packages. It was aimed at making it easy to get the most common type of package created and also to be used as a starting point before doing the rest by hand.
Not sure if it helps, but I have put the policy manuals at https://github.com/alanbu/RiscPkg-Policy/tree/master/Manuals/RiscPkg-Policy and you may be able to use the history feature to get to the 0.4.0 version. |
Chris Mahoney (1684) 2165 posts |
Thanks… alas, I have used a 0.5.0 feature so I’d better tweak my Control file :) |
Chris Mahoney (1684) 2165 posts |
Since nobody’s reported any further bugs, I’ve incremented the version number to 1.0, changed the licence to BSD, and have put the source on my site. The latest binary is available on the same site, or through PackMan. I’ve tried to comment the source so that someone new to RISC OS could still find it understandable. I’d appreciate it if any tweaks could be fed back to me so that I can update the “master” copy. As a side note, is there any sort of etiquette I should know about when mixing open-source with the RISC OS allocation system? I “own” the “Uptime” module name and *Uptime command and I’m not sure how this all works when the BSD licence allows anyone to build their own version. |
Chris Mahoney (1684) 2165 posts |
Just thinking aloud a little… since Uptime calculates the “real” monotonic time considering rollover, is there any interest in a future version offering a SWI so that other apps can get that corrected time? I haven’t looked into the practicality or necessity of that, but does it sound like it could be useful for something? |
Chris Mahoney (1684) 2165 posts |
At the risk of cluttering my own thread a little (but it HAS been six months), I have a couple of questions around internationalisation. Is there a recommended way to internationalise a module? I’ve cherry-picked a couple of existing modules in CVS and found that they handle message lookups in different ways. Is there a “new way” and an “old way”? The other question is around whether this is necessary at all; when you run “uptime” on a Unix system then the results are in English regardless of the UI language. Are RISC OS *Commands typically translated or should they always return English? If someone’s parsing the output then having it consistent would make sense. |
Rick Murray (539) 13840 posts |
I think you may want to push a file into Resources? A simple module ought to give you some pointers. |
Chris Mahoney (1684) 2165 posts |
There didn’t seem to be much interest in a SWI but I think you’re right; it’ll be better to ignore potential parsing and just add a SWI later if there’s a request for one (or maybe do it anyway, request or no). Yes, a simple module should give pointers but they seem to do things differently :) I’ll just look at a few more and see whether I can see any consistent patterns. Thanks. Edit: Just found this, which looks useful! const char *module_lookup_msg(const char *token) { if (_swix(MessageTrans_Lookup, _INR(0,7), msg_struct, token, &msg_buff, sizeof(msg_buff), 0, 0, 0, 0) != NULL) { return ""; } return (const char *)&msg_buff; } There’s some other stuff around opening/closing the file, but it looks like this’ll get me on the right track :) |
Sprow (202) 1158 posts |
I don’t think so, it’s usually a matter of taste, or what happened to be in the module when it was created. The steps are similar though, and you’ve 2 basic routes for RAM loading modules:
For very occasional lookups, say you only have 1 error message, this can be cut down to:
A few modules in CVS include the tboxlibs/toolbox.h for the definition of MessagesFD. I’m not a big fan of that because you end up with a dependency on the Toolbox even though your module isn’t linked against it, but each to their own.
The command name isn’t translated (*Obey is always *Obey) but the text it prints out certainly should be. Tip 1: keep your token names short and not english words. Then to check for success load the (unsqueezed) module into a hex editor and look for english text, there should be none, just the token names. Tip 2: remember that you can’t assume english rules, so don’t be tempted to build phrases by sticking words together. Not everyone makes a plural by adding an ‘s’ on the end for example. Tip 3: if there’s a fatal error in your initialisation be careful not to return an error pointer that’s in static storage in your module, because your module’s just about to die, and the RMA might get recycled. Use one of MessageTrans’ built in buffers. |
Chris Mahoney (1684) 2165 posts |
Thanks; I’d found reference to Resources() but wasn’t sure where it was coming from; knowing that it’s from the makefile will probably help! Hopefully I’ll get time to play with this on the weekend. |
Chris Mahoney (1684) 2165 posts |
I have finally come back to this; I started it back in early September but couldn’t get it working. The problem ended up being that I still had “CUSTOMRES = no” in my makefile :) Version 1.10 is now available on my site and it has been submitted to PackMan so it should show up there soon. From a user-facing perspective it should be the same as ever, but it’s now localisable and doesn’t do stuff like appending “s” to make a plural. I may eventually get a SWI handler in there, but it’s not in 1.10. Known issue: *Help Uptime will always return English. I noticed that after packaging everything up and haven’t bothered to fix it yet. |
Chris Mahoney (1684) 2165 posts |
The observant may have noticed an update come through PackMan recently. There’s no new functionality, but the code is now using SyncLib instead of turning IRQs on and off, so it’s a little bit “cleaner”. Hopefully I’ve done it all correctly; it hasn’t crashed my machine yet :) Non-PackMan users can get Uptime 2.0 (and its source) from my site. |
Jeffrey Lee (213) 6048 posts |
Wait 250 days and maybe you’ll get a crash! CallAfter / CallEvery routines execute in an interrupt context (aka “in the background”). You’re using a mutex, which mutex.h says “is not appropriate if you need it to always be possible to lock the mutex from the background (e.g. in an interrupt handler).” If the CallEvery fires while the *uptime command is in get_mt, then you’ll deadlock the system because there’s no way for the interrupt handler to yield until the mutex is unlocked. You want to use a spinlock instead (which will turn IRQs on & off, but is essentially your only option unless we were to change ticker handlers to be called from a thread context). The basic rules are that if something needs to be writable from an interrupt handler it needs to be protected by a spinlock; if it only needs to be readable from an interrupt handler then it should be protected by a spinrwlock; and if it’s only ever accessed from the “foreground” (i.e. some kind of thread context) then you can use a mutex. Also if the goal was to make it thread-safe then you’re still falling short because you’re reading mt + rollovercount while the mutex which protects them isn’t held. |
Chris Mahoney (1684) 2165 posts |
Well, it seems that I’ve messed things up a bit! First of all, the reason for the change. I’d submitted the previous version (1.10) to ROOL in case they wanted to build it into the OS. One of the suggestions that came back was to use SyncLib instead of disabling IRQs. Unfortunately this sort of thing is a bit over my head and I had to glean what I could from Stack Overflow posts and the like. I should’ve seen that note in mutex.h and realised that it wasn’t a good idea. In the meantime I’m rolling PackMan back to 1.10 (hopefully this works). For all I know 1.10 might be doing the “wrong” thing too, but at least it hasn’t had any reported crashes! I’ve also “removed” 2.0 from my site; i.e. the files are no longer linked. However, the binary and source are still physically there for anyone that’s curious. [Edit: Have subsequently rejigged the site, so these links no longer work] When I have some time I’ll try to find some sort of “multi-threading for dummies” and learn how to do this properly. Thanks for pointing out that I’d got it wrong… and next time I’ll do a beta instead of chucking it straight into PackMan! :) |
Jeffrey Lee (213) 6048 posts |
Since we don’t have a threading guide for RISC OS (for obvious reasons), and I don’t think we even have a proper definition for what “foreground” and “background” are (or at least nothing that’s up-to-date), here’s a start of a wiki page to help you along the way: https://www.riscosopen.org/wiki/documentation/show/Program%20Environment |
Chris Mahoney (1684) 2165 posts |
A year on, I have a call for volunteers. I’ve had a chat with ROOL about bringing Uptime’s functionality into the OS. One of the suggestions was to move the “timer rollover count” logic into the kernel and expose it via a new OS_ReadSysInfo subreason. However, I lack the assembly skills necessary for this. Does anyone want to put their hand up? The necessary logic is already in my module’s C code but I’m happy to summarise it here if it’ll simplify things. Edit: ROOL’s actual wording was “extend the Kernel to track overflows of monotonic time and present this as a new OS_ReadSysInfo subreason (returning a 64 bit integer)”. This may indicate returning a 64-bit monotonic time, rather than just the rollover count. |
Jeffrey Lee (213) 6048 posts |
Yeah, that does sound a bit like they’re asking for a 64bit monotonic timer. In which case it’s essentially a subset of what I’ve been working on (except mine will most likely be microseconds instead of centiseconds). So it might be worth pointing ROOL towards that thread. |
Chris Mahoney (1684) 2165 posts |
I’d seen that thread in the past but had completely forgotten about it! It certainly sounds like it could do the trick (and microseconds are unlikely to be a problem). I’m happy to make a “new timers” version of Uptime when the time comes. Thanks for replying :) |
Pages: 1 2