Subject:
|
I'm being stupid. But how?
|
Newsgroups:
|
lugnet.robotics.rcx.legos
|
Date:
|
Thu, 29 Apr 1999 22:25:07 GMT
|
Viewed:
|
1316 times
|
| |
| |
I've written a test program using the 19990330 LegOS snapshot[1], and
it's misbehaving oddly.
The program looks like this:
(the headers are the result of my frobbing the LegOS headers to refer to
<mindstorms/{legOS header}>...)
#include <mindstorms/rom/lcd.h>
#include <mindstorms/sys/tm.h>
#include <mindstorms/direct-button.h>
#include <mindstorms/conio.h>
#include <mindstorms/unistd.h>
#ifndef __cplusplus
typedef int bool;
#define true 1;
#define false 0;
#endif
pid_t taskPrimary,taskKiller;
bool deadPrimary;
/* Return when a button is pressed, or released, respectively. */
static wakeup_t buttonPress (wakeup_t data)
{
return (PRESSED (button_state(),data));
}
static wakeup_t buttonRelease (wakeup_t data)
{
return (RELEASED (button_state(),data));
}
/* This task does all the work. */
static int mainTask (int argc, char *argv[])
{
deadPrimary=false;
cputs ("foop");
lcd_refresh();
sleep (10);
deadPrimary=true;
return 0;
}
/* This task sleeps until triggered, then kills everyone. It is critically
necessary, or crashes elsewhere might lock up the whole system.
Note that it has to wait for *all* termination conditions :( possibly I'll
have it wait on a list of functions, sort of like TP's ExitHandlers.
We might also implement timed execution, for eg timed contests &c, with
this. */
static int killerTask (int argc, char *argv[])
{
wait_event (buttonRelease,BUTTON_RUN); /* Let the user release [Run] */
msleep (100);
wait_event (buttonPress,BUTTON_RUN); /* Wait for our signal */
if (!deadPrimary)
{
lcd_refresh();
kill (taskPrimary); /* LART everyone, if they are not dead */
}
kill (taskKiller);
return 0;
}
int main (void)
{
/* It is critically important that all even vaguely complex code
execute in multi-process mode, slower or no, unless you like
dismantling your lego models all the time... */
deadPrimary=true;
taskPrimary=execi (&mainTask,0,NULL,1,DEFAULT_STACK_SIZE);
taskKiller=execi (&killerTask,0,NULL,128,384); /* Small stack, high priority; tasks above this are in critical sections */
lcd_refresh(); /* Update the nr of tasks counter, ugh, probable LegOS bug */
tm_start();
return 0;
}
The purpose of this code is simply that the second task should act as a
trapdoor, killing the world if the user hits {Run}; and indeed if {Run}
is hit, it works. But if {Run} is *not* hit, the box locks up at some
point after decrementing the total number of tasks.
But the really wierd bit is that reversing the order of the execi()s
causes the problem to go away! Now the execi() order should have no
effect; after all they'll end up in the same order in the task priority
queue anyway... my best guess so far is a bug in the priority queue
code. I'm chasing, but it's quite hard to chase when you can only output
a character or so at a time :)
I'm really asking if this has been fixed already; if it has I don't need
to bother chasing the bug myself :)
btw, great OS (or maybe it's more `C library and monster startup code'
;) )
[1] and egcs-1.1.2-release, and binutils-2.9.1.0.22b, and
i586-pc-linux-gnu -> h8300-hitachi-hms cross tools...
--
`I wanted to be a fascist dictator, but it's hard getting an interview
without the experience. I thought network management would be
a good stepping stone.' --- Robert Franklin
|
|
Message has 1 Reply: | | Re: I'm being stupid. But how?
|
| (...) Hahaha, regarding that LegOS is more of a library than an OS, my opinion too. But you have to admit the name has some appeal, even if it is something of a misnomer... :) Clearly it says something about TLG's attitude toward LegOS that they (...) (26 years ago, 3-May-99, to lugnet.robotics.rcx.legos)
|
5 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|