Welcome, Guest. Please login or register.

Author Topic: Best and fast way to AllocMem within an interrupt :Semaphores ?  (Read 7418 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Best and fast way to AllocMem within an interrupt :Semaphores ?
« on: November 22, 2006, 03:34:02 PM »
Hi. I'll 1st explain what I want to do. I have self propagating sequence of time intervals that are received in a MsgPort through PA_SoftInt or 3 set in the MsgPorts message arrival settings (mp_Flags). When a message is received I want to be able to change a forward linked list of structures wich have directory locks, wich are used by a process that records stuff to the HD according to received messages. There's no problem with race conditions, because the locks are changed/freed by the HD recorder process itself (a special message sent to it specifies what to change). However I'm having a problem sending the messages to it because I can't use any system memory allocation functions from an interrupt, hardware or software. I can however, according to the RKM Libs, use PutMsg() and Signal().
The solution I've invented is like this (I think it's pretty cool:)) Use a Semaphore to protect a BOOL variable or whatever piece of data that will serve as an arbitration. The Semaphore will be held constantly by another very small process that allocates memory and that's waiting for a signal to do it. The interrupt processing code will signal it to do it. Up to this point nothing will happend cause interrupts, even software ones, allways have an higher priority than tasks. Then the interrupt processing code will try to Obtain the said Semaphore exclusively, wich will of course make the memory allocating function work. After it's allocated the Memory to a shared memory address it relinquishes the Semaphore and the interrupt processing code can then use the allocated memory to send a message to the HD recorder process, wich frees the memory after processig the message.

I have 3 questions:
1- When the interrupt code loses the CPU when it ObtainSemaphore()s the system will be multitasking or only the small memory allocating process will execute ?
2- The RKM Libs has a list of functions that you can use from an interrupt and ObtainSemaphore is not one of them. This would make my solution not work, however the Semaphore system is documented to use signals and Signal() is a function you can use. I suppose the Semaphore lists could be inconsistent, but I wouldn't add the said semaphore to the system Semaphore list.
3- This is difficult, interesting, challenging and frustrating:lol: Is there a better way to achieve what I want to do ? Suggestions wanted/accepted.
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #1 on: November 22, 2006, 04:06:27 PM »
You can't use semaphores from an interrupt (or anything that might call Wait()).

AllocMem() itself does not break forbid (or disable), so why not just call AllocMem directly?
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #2 on: November 22, 2006, 04:13:18 PM »
Short and strong answer to a long post 8-) Thanks for taking the time. I actually knew you couldn't use Wait, even indirectly but had forgot about it...

I'll have to try to figure out another solution. I could allocate the memory beforehand but there's no guarantee as to how many interrupts can happen within a period of time (will depend on user settings).
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #3 on: November 22, 2006, 04:16:10 PM »
"AllocMem() itself does not break forbid (or disable), so why not just call AllocMem directly?"

The RKM Libs says you can't use AllocMem cause the system memory lists might be inconsistent (the interrupt might have interrupted a system operation that was manipulating them and hadn't yet finished).
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #4 on: November 22, 2006, 04:20:08 PM »
That would be true if it was an interrupt, but in this case it's not: The OS is inside PutMsg to your msgport, not AllocMem. At least I can't think of any condition in which the port could be PutMsg()d while the memory list is in inconsistent state. This at least with mp_Flags of 3.

PA_SOFTINT might be another story.
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #5 on: November 22, 2006, 04:40:58 PM »
Aha! That's nice. I almost changed the code to use PA_SOFTINT instead cause with mp_Flags == 3 the system is in Disable, while PA_SOFTINT is just Forbid I think.
I suppose with PA_SOFTINT there's no easy way around to what I want to do ?

\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #6 on: November 22, 2006, 04:49:09 PM »
Well even though softint would break forbid (IIRC it doesn't), it still is quite unlikely that someone would send message to your msgport while memlist is inconsistent. So IMO PA_SOFTINT is pretty much as safe.
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #7 on: November 22, 2006, 05:30:42 PM »
"Well even though softint would break forbid (IIRC it doesn't), it still is quite unlikely that someone would send message to your msgport while memlist is inconsistent. So IMO PA_SOFTINT is pretty much as safe."

I got various processes running, some of which can allocate memory to send messages to the HD recorder process very frequently, so if softint breaks forbid maybe it could happend.
Anyway, I'm tired, for now I'm just gonna keep 3 in mp_Flags (and use AllocMem/Vec). :-)

Cheers
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #8 on: November 22, 2006, 07:40:33 PM »
Quote
I got various processes running, some of which can allocate memory to send messages to the HD recorder process very frequently, so if softint breaks forbid maybe it could happend.

And all memory allocation routines Forbid/Permit internally. How can them PutMsg inside memory allocation/free?
 

Offline ChaosLord

  • Hero Member
  • *****
  • Join Date: Nov 2003
  • Posts: 2608
    • Show only replies by ChaosLord
    • http://totalchaoseng.dbv.pl/news.php
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #9 on: November 22, 2006, 08:29:20 PM »
1. Calculate the maximum amount of mem your interrupt routine could ever possibly need.

2. Allocate that much mem for it at the very start of your program.

3. Problem solved.



p.s. Whether AllocMem() breaks Forbid() or Disable() or whatnot is completely irrelevant because one never knows how long an AllocMem() will take.  After some days of running normal software (or just 1 single day of running a bunch of MUI software) I personally guarantee you that AllocMem() will take 3.8 forevers due to excessive memory fragmentation.  If just one of your interrupts takes even half of a forever then your buffers will all overflow or underflow and your software will go kaplooie.

Wanna try a wonderfull strategy game with lots of handdrawn anims,
Magic Spells and Monsters, Incredible playability and lastability,
English speech, etc. Total Chaos AGA
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #10 on: November 22, 2006, 08:31:26 PM »
@ChaosLord

I'll pretend you never suggested that.
 

Offline Zac67

  • Hero Member
  • *****
  • Join Date: Nov 2004
  • Posts: 2890
    • Show only replies by Zac67
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #11 on: November 22, 2006, 09:57:54 PM »
ChaosLord's suggestion does have a point: depending on how exactly mem is allocated/freed, fragmentation might become a problem. If you allocate everything needed in advance, there's nothing to worry about. And you'd produce less overhead (for realtime requirements) - as long as you can live with the memory usage.
Also, I can't really imagine AllocMem() working inside an interrupt...
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #12 on: November 22, 2006, 10:10:05 PM »
It's no interrupt, that is: it can't be in the middle of memory allocation/free.

Using static size buffers that are "large enough (to certain point)" is rather silly IMO. It wastes memory and will fail if something needs more memory after all.

If you're worried about performance, you can use simple pooled allocation with Allocate/Deallocate.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #13 on: November 23, 2006, 08:22:53 PM »
Slightly off-topic

Does anybody have any performance statistics for the different memory allocation functions supported by exec?

I'm interested in the time taken to allocate/deallocate as a function of allocation size, for each method*


*I'm fully aware that this would likely change as memory becomes fragmented.
int p; // A
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Best and fast way to AllocMem within an interrupt :Semaphores ?
« Reply #14 on: November 23, 2006, 08:38:08 PM »
They're all based on Allocate()/Deallocate(), so they're quite fast while memory is not fragmented.

However, FreePooled() is a bit special: It gets really slow due to the puddle scanning to find the proper memory header to call Deallocate() on. This gets exponentally slow.

AmigaOS 3.9 BB2 fixed this by using the new AVL tree binary balanced tree instead of simple linked list for the puddles.