19-Apr-2024 12:41 GMT.
UNDER CONSTRUCTION
Anonymous, there are 114 items in your selection (but only 14 shown due to limitation) [1 - 50] [51 - 100] [101 - 114]
[Forum] OS4 design for ObtainSysList/ReleaseSysListANN.lu
Posted on 11-Jul-2004 20:44 GMT by adesigner (Edited on 2004-07-12 02:34:47 GMT by Christophe Decanini)114 comments
View flat
View list
"In the documentation of FindPort() it is said that you should use ObtainSysList(OSL_PORTLIST) and ReleaseSysList() instead of Forbit() and Permit() in OS4."
www.amigaworld.net thread

I believe this is broken design, you can't mix Forbid and semaphore locking. (Edit by Christophe: It has been confirmed that this solution was rejected for OS4) [sort of pseudo code follows]

" static struct MsgPort *Port;

int InitThePort(void)
{
struct MsgPort *newport;
int result = 0;

ObtainSysList(OSL_PORTLIST); /* Forbid(); */
Port = FindPort(MYPORTNAME);
if (Port) {
result = 2;
} else {
newport = AllocMem(sizeof(*newport), MEMF_PUBLIC);
if (newport) {
/* ... init newport ... */
AddPort(newport);
Port = newport;
result = 1;
} else result = 0;
} else result = 0;

ReleaseSysList(OSL_PORTLIST); /* Permit(); */
return result;
}
"

The problem here is that if some other app is using Forbid() locking, it can easily end up AddPort()ng duplicate port with the same name.

This can happen if task A using ObtainSysList reaches just before AddPort, and Task B using Forbid gets scheduled to run. This task will then Forbid, FindPort and get NULL too. Task B (that is run within Forbid) will now continue and create new port and add it to system via AddPort.

Next Task B Permits and lets other tasks run. Now Task A gets to run and continues to AddPort *duplicate* port.

Further problems may arise if application FindPorting for this port is using Forbid. There the port is actually found *before* InitThePort reaches ReleaseSysList. Now if some further initializing of resources is done before this call, messages might get lost in case these initializations fail, and the app assumes no messages can be in the port (the port list is locked after all, so there should't be any, right?).

RemPort has similar issues, but there the problem is that FindPort can find the port even after ObtainSysList is called for RemPort, and thus more messages might appear in the port even after this ObtainSysList.

Note that AddPort/FindPort itself must not break Forbid. There are a lot more ways that things can break down, I just listed some. Also here I only considered public port list, other system lists have even greater problems.

I ask developers to review these findings and if I am wrong, correct me.

OS4 design for ObtainSysList/ReleaseSysList : Comment 101 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 10:43 GMT
In reply to Comment 99 (Fabio Alemagna):
Sorry, no points. Wrong is wrong. Disabling task switching doesnt implicate anything in regards to several cpus.
OS4 design for ObtainSysList/ReleaseSysList : Comment 102 of 114ANN.lu
Posted by Fabio Alemagna on 16-Jul-2004 10:49 GMT
In reply to Comment 101 (Ketzer):
> Sorry, no points. Wrong is wrong. Disabling task switching doesnt implicate
> anything in regards to several cpus.

It implicates that two running tasks can enter a Forbid()-protected at the same time, which in turn means that - of course - Forbid() has to act a s a spinlock too.

It's not my fault of obvious things aren't obvious to everyone. Of course, it means nothing to you that I made it explicit in the subsequent posts, right?
OS4 design for ObtainSysList/ReleaseSysList : Comment 103 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 11:00 GMT
In reply to Comment 98 (Fabio Alemagna):
Alright, some things would have to be done different (workbench startup), some things might break completely. If one gets rid of Forbid that way, thats worth it.

>> Such relying on implementation details is what got us into that compatibility
>> mess to start with. So imo, break it, better now than never.

> That's not an implementation detail, it's a specification requirement. A task with higher priority than another task will never be preempted by that other task. This is a requirement of the interface, not an implementation detail. What would be the point in having priorities at all, if the scheduler were able to give whatever meaning that it wanted?

It assumes that task priority doesnt change. What if the scheduler were to change, eg. able to alter priorities based on various algorithms? If an area is protected by a semaphore, it is good practice to *use* that semaphore.

>>> You see, a global semaphore would solve exactly nothing here.

>> Sure, in that particular case, but again, what program actually uses that?

> Apparently, more than you'd like to know.

Besides starting from workbench, which surely could be handled in a different way, im still curious what programs would actually break.
OS4 design for ObtainSysList/ReleaseSysList : Comment 104 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 11:11 GMT
In reply to Comment 102 (Fabio Alemagna):
>> Sorry, no points. Wrong is wrong. Disabling task switching doesnt implicate
>> anything in regards to several cpus.

> It implicates that two running tasks can enter a Forbid()-protected at the same time, which in turn means that - of course - Forbid() has to act a s a spinlock too.
> It's not my fault of obvious things aren't obvious to everyone.

Nice attitude in discussions. Claim something wrong, then claim its obvious that its wrong and one should have known what you thought while writing that claim.

> Of course, it means nothing to you that I made it explicit in the subsequent posts, right?

Like most people I read from top down.
OS4 design for ObtainSysList/ReleaseSysList : Comment 105 of 114ANN.lu
Posted by Fabio Alemagna on 16-Jul-2004 11:18 GMT
In reply to Comment 103 (Ketzer):
> Alright, some things would have to be done different (workbench startup),

You can't make it different without breaking binary compatibility.

> some things might break completely. If one gets rid of Forbid that way, thats
> worth it.

Unfortunately, breaking "some things" could mean breaking everything, because you are playing with shared resources here, and if breaking something means possibily creating state inconsistency, not just the "culprit" application will suffer, but the whole system.

> > That's not an implementation detail, it's a specification requirement. A
> > task with higher priority than another task will never be preempted by that > > other task. This is a requirement of the interface, not an implementation
> > detail. What would be the point in having priorities at all, if the
> > scheduler were able to give them whatever meaning that it wanted?

> It assumes that task priority doesnt change. What if the scheduler were to
> change, eg. able to alter priorities based on various algorithms?

Priorities don't have to change, no point in letting the user chose any priorities at all, then. What may change is the way tasks *with the same priority* are scheduled.

> If an area is protected by a semaphore, it is good practice to *use* that
> semaphore.

But here we're talking about applications that do not use a semaphore. As bad as it can be, there are such applications.

> Besides starting from workbench, which surely could be handled in a different
> way, im still curious what programs would actually break.

I don't know exactly _which_ programs would break, but since that example was given to me by Martin Blom, I assume something of his would break.
OS4 design for ObtainSysList/ReleaseSysList : Comment 106 of 114ANN.lu
Posted by Fabio Alemagna on 16-Jul-2004 11:21 GMT
In reply to Comment 104 (Ketzer):
> Nice attitude in discussions. Claim something wrong, then claim its obvious
> that its wrong and one should have known what you thought while writing that
> claim.

It's named "logical inference". The only possible solution was the one I've then made explicit. I'm a lazy typer, I prefer leaving out obvious things rather than having to write them explicitely.

> Like most people I read from top down.

1) That doesn't imply that you have to reply from top down too.
2) By now you should have read also the other posts, hence why are we still discussing this?
OS4 design for ObtainSysList/ReleaseSysList : Comment 107 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 11:33 GMT
In reply to Comment 105 (Fabio Alemagna):
>> Alright, some things would have to be done different (workbench startup),

> You can't make it different without breaking binary compatibility.

I really dont understand this ... this should be a rather simple change in workbenchs process creation coding? (Added to the changed behaviour of Forbid).

>> some things might break completely. If one gets rid of Forbid that way, thats
>> worth it.

> Unfortunately, breaking "some things" could mean breaking everything, because you are playing with shared resources here, and if breaking something means possibily creating state inconsistency, not just the "culprit" application will suffer, but the whole system.

To summarize, Im proposing to declare Forbid() obsolete and replace its implementation by one using semaphores. This should be able to take care of most prior uses.

>> It assumes that task priority doesnt change. What if the scheduler were to
>> change, eg. able to alter priorities based on various algorithms?

> Priorities don't have to change, no point in letting the user chose any priorities at all, then.

It would be even worse if the user were able to choose priorites ...
Didnt Executive do something like that?

>> If an area is protected by a semaphore, it is good practice to *use* that
>> semaphore.

> But here we're talking about applications that do not use a semaphore. As bad as it can be, there are such applications.

Yes, its bad, yes, they probably will break, yes, they should break.
OS4 design for ObtainSysList/ReleaseSysList : Comment 108 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 11:38 GMT
In reply to Comment 106 (Fabio Alemagna):
Sure, we can stop right here ... just so you understand what my problem is.

a) Cannot happen when disabling task switching. -> wrong
b) Cannot happen when disabling task switching and protecting forbid with a semaphore. -> ok
c) Cannot happen when protecting forbid with a semaphore. -> still ok

Writing this, I realize that your example of a high priority task not using forbid and a low priority task using forbid can still break b) and c) in a mcpu system. In essence forbid really would have to halt all other tasks to be compatible. Yuck.
OS4 design for ObtainSysList/ReleaseSysList : Comment 109 of 114ANN.lu
Posted by Fabio Alemagna on 16-Jul-2004 11:56 GMT
In reply to Comment 107 (Ketzer):
> > You can't make it different without breaking binary compatibility.
>
> I really dont understand this ... this should be a rather simple change in
> workbenchs process creation coding? (Added to the changed behaviour of
> Forbid).

You can, since some time, let CreateNewProc take care of freeing the seglist for you, which would partly solve the problem... if it were't for the fact that the program would still use Forbid(). Now, if Forbid() were a no-op, that would work just fine, buf if Forbid() were to lock a global semaphore, then this semaphore should be unlocked before the process exited. Although the latter is feasible, you should ask yourself whether such a special treatment should be reserved to this global semaphore, whilst other semaphores don't get unlocked when the process exits.

In any case, in that particular instance the problem is somewhat solvable. It's actually what I had in mind when I first proposed here and on the AROS-Dev list to implement Forbid()/Permit() as a global semahore locking/unlocking, but then Martin Blom gave his examples, and the rest is history...


> > Unfortunately, breaking "some things" could mean breaking everything,
> > because you are playing with shared resources here, and if breaking
> > something means possibily creating state inconsistency, not just the
> > "culprit" application will suffer, but the whole system.

> To summarize, Im proposing to declare Forbid() obsolete and replace its
> implementation by one using semaphores. This should be able to take care of
> most prior uses.

Yes, most but not all, as explained. How do you solve the task creation issue? Martin says lots of programs do it that way. If Forbid() had to simply lock a global semaphore, that code would not work as expected, giving a change to the newly created task to run before its userdata were properly set, possibly creating all kind of bad behaviours.

> > Priorities don't have to change, no point in letting the user chose any
> > priorities at all, then.

> It would be even worse if the user were able to choose priorites ...

The use _is_ able to change priorities. When I say "user" I mean the user of the API, that is the programs. Of course also the human user is able to change priorities, but she should never play with such things unless she knew what she'd be doing.


> Didnt Executive do something like that?

Executive adds another priority level to the tasks, which is named the "nice" level. This priority is dynamically adjusted, but the global one, afaik, is not. And shouldn't be. Imagine what would happen if intuition task's priority were lowered from 20 to, say 5, and the one for the ide.device's task were 10: any access to the disk would make everything gui-related suddendly block.

> > But here we're talking about applications that do not use a semaphore. As
> > bad as it can be, there are such applications.

> Yes, its bad, yes, they probably will break, yes, they should break.

I wish it were that easy, but it's not.
OS4 design for ObtainSysList/ReleaseSysList : Comment 110 of 114ANN.lu
Posted by Alkis Tsapanidis on 16-Jul-2004 12:04 GMT
In reply to Comment 103 (Ketzer):
At this point, breaking any old Amiga software in order to advance is stupid for
a very simple reason. There are NOT any alternatives to that software yet and
won't be in the near future.
OS4 design for ObtainSysList/ReleaseSysList : Comment 111 of 114ANN.lu
Posted by Alkis Tsapanidis on 16-Jul-2004 12:08 GMT
In reply to Comment 107 (Ketzer):
When something bad is in use by (example) 40% of all existing programs breaking
would be worse, until there are replacements.
OS4 design for ObtainSysList/ReleaseSysList : Comment 112 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 12:16 GMT
In reply to Comment 109 (Fabio Alemagna):
> How do you solve the task creation issue? Martin says lots of programs do it that way. If Forbid() had to simply lock a global semaphore, that code would not work as expected, giving a change to the newly created task to run before its userdata were properly set, possibly creating all kind of bad behaviours.

The new task would have to immediately start with a Forbid/Permit pair :-/
More realistically you would have to play with the scheduler, introducing a state "created" and only allowing the transistion to running/waiting when the global semphore is read accessible. Cant think of anything better right now.

[priorities]

There are reasons and ways task priorities can change. Assuming your task has a certain priority doesnt net any real benefit and is a possible source of hard to track problems. This should only (and only if there isnt another way) be acceptable for system tasks.

> > But here we're talking about applications that do not use a semaphore. As
> > bad as it can be, there are such applications.

>> Yes, its bad, yes, they probably will break, yes, they should break.
> I wish it were that easy, but it's not.

In essence Forbid() is hazardous to a multitasking environment and sooner or later it must be remove/changed to an acceptable behaviour. And rather than doing it later when *new* software uses this, it should be changed now. Imo, its the only choice.
OS4 design for ObtainSysList/ReleaseSysList : Comment 113 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 12:27 GMT
In reply to Comment 111 (Alkis Tsapanidis):
If it was 40% of the applications ... my guesstimate is its still a lot less than that if one accepts a few well placed compatibility hacks for a while.
OS4 design for ObtainSysList/ReleaseSysList : Comment 114 of 114ANN.lu
Posted by Ketzer on 16-Jul-2004 12:42 GMT
In reply to Comment 112 (Ketzer):
Giving this some more thought (yes, Im at work and weekend is calling) ...

Currently Forbid() will break whenever the task enters a waiting state.
A semaphore-Forbid() wont. Now, if this change would have consequences i dont know.
Anonymous, there are 114 items in your selection (but only 14 shown due to limitation) [1 - 50] [51 - 100] [101 - 114]
Back to Top