AsyncUpdater which don't malloc


#1

Hi Jules,

I was wondering if there might be a way to modify AsyncUpdater
so it doesn’t malloc in triggerAsyncUpdate

In our code, some DSP stuff send a signal to the UI so it takes changes into account and those signals call triggerAsyncUpdate and I usually try to avoid to call malloc in the realtime audio thread.

Thanks


#2

Yes, I understand the problem, but it’s kind of tricky because the async updater works by sending a message, and that message needs allocating.
There are other simple tricks you could use if timing isn’t critical, like making the audio thread set a flag, and using a UI timer to check the flag every so often.


#3

How about creating a message pool which preallocates a certain number of messages, and fetching memory from there?


#4

That’d be a good solution for this specific case, though I wouldn’t want to burden the normal asyncupdater class with that kind of overhead when it’d only be helpful in realtime threads like this.


#5

Why not just add a “ID” integer to the Component class plus another integer that the programmer can use for his purposes?
This way the programmer could assign an id to the component. The realtime thread would just call a function, such as setComponentValue(int id, float value) and the rest would be done with a big switch. The second integer could be used as a redraw flag for instance and so the programmer could install a Timer that checks all components he wants for the flag and call repaint() in another Thread than the DSP thread.
This is at least how I did the whole thing in my apps. But this also forced me to rewrite all sliders, buttons, …
If the 2 integers would be there in Component, this would make life much easier sometimes.


#6

Would something like this work? (haven’t tested it)

AsyncUpdatorWithoutMalloc.h

class AsyncUpdatorWithoutMalloc
{
public:
	//==============================================================================
	/** Creates an AsyncUpdatorWithoutMalloc object. */
	AsyncUpdatorWithoutMalloc() throw();

	/** Destructor.

	If there are any pending callbacks when the object is deleted, these are lost.
	*/
	virtual ~AsyncUpdatorWithoutMalloc();

	//==============================================================================
	/** Causes the callback to be triggered at a later time.

	This method returns immediately, having made sure that a callback
	to the handleAsyncUpdate() method will occur as soon as possible.

	If an update callback is already pending but hasn't happened yet, calls
	to this method will be ignored.

	It's thread-safe to call this method from any number of threads without
	needing to worry about locking.
	*/
	void triggerAsyncUpdate() throw();

	/** This will stop any pending updates from happening.

	If called after triggerAsyncUpdate() and before the handleAsyncUpdate()
	callback happens, this will cancel the handleAsyncUpdate() callback.
	*/
	void cancelPendingUpdate() throw();

	/** If an update has been triggered and is pending, this will invoke it
	synchronously.

	Use this as a kind of "flush" operation - if an update is pending, the
	handleAsyncUpdate() method will be called immediately; if no update is
	pending, then nothing will be done.
	*/
	void handleUpdateNowIfNeeded();

	//==============================================================================
	/** Called back to do whatever your class needs to do.

	This method is called by the message thread at the next convenient time
	after the triggerAsyncUpdate() method has been called.
	*/
	virtual void handleAsyncUpdate() = 0;

	/** Static callback function to handle asynchronous calls from the
	message thread
	*/
	static void* msgThreadCallback(void* ptr);

private:
	bool asyncMessagePending;
};
AsyncUpdatorWithoutMalloc.cpp


AsyncUpdatorWithoutMalloc::AsyncUpdatorWithoutMalloc() throw()
: asyncMessagePending(false)
{

}

AsyncUpdatorWithoutMalloc::~AsyncUpdatorWithoutMalloc()
{

}

void* AsyncUpdatorWithoutMalloc::msgThreadCallback( void* ptr )
{
	AsyncUpdatorWithoutMalloc* pThis = (AsyncUpdatorWithoutMalloc*)ptr;
	pThis->handleUpdateNowIfNeeded();
	return (void*)0;
}

void AsyncUpdatorWithoutMalloc::triggerAsyncUpdate() throw()
{
	if (!asyncMessagePending)
	{
		asyncMessagePending = true;
		MessageManager::getInstance()->callFunctionOnMessageThreadAsynchronously(&AsyncUpdatorWithoutMalloc::msgThreadCallback, (void*)this);
	}
}

void AsyncUpdatorWithoutMalloc::cancelPendingUpdate() throw()
{
	asyncMessagePending = false;
}

void AsyncUpdatorWithoutMalloc::handleUpdateNowIfNeeded()
{
	if (asyncMessagePending)
	{
		asyncMessagePending = false;
		handleAsyncUpdate();
	}
}

Edit: Edited to match with my next post

#7

Dammit. It won’t, since the callfunctionon… is synchronous, the rt thread will halt, which I guess the OP doesn’t want. How 'bout an asynchronous variant of that, Jules? :slight_smile:


#8

An asynchronous callFunctionOnMessageThread would still need to allocate a message and send it.

Something along these lines this is probably your best bet:

[code]class Async : public Timer
{
bool volatile triggered;

Async()
{
    triggered = false;
    startTimer (1000 / 30);
}

void trigger()
{
    triggered = true;
}

void timerCallback()
{
    if (triggered)
    {
        triggered = false;
        doTheCallback();
    }
}

};[/code]

And it could be optimised to reduce the timer rate when no callbacks are happening, and increase it when it’s busy.


#9

Really? In Win32 case:

//==============================================================================
bool MessageManager::callFunctionOnMessageThreadAsynchronously (MessageCallbackFunction* callback,
                                                   void* userData)
{
    if (MessageManager::getInstance()->isThisTheMessageThread())
    {
        // Don't care about return value in this case
        (void)(*callback) (userData);
        return true;
    }
    else
    {
        // No deadlock probs here...
        return (PostMessage (juce_messageWindowHandle,
                                    specialCallbackId,
                                    (WPARAM) callback,
                                    (LPARAM) userData) != 0);
    }
}

No allocations needed. Probably analogous for Mac/Linux case. My earlier post is edited to match this proposal.


#10

Well I certainly don’t trust the PostMessage function to be safe for real-time use! Who knows what allocations and locking might happen in there!

Definitely the safest way is what I suggested with a timer, and testing a flag 30 times a second will use a negligible amount of cpu. Another good solution would be to signal a waitableevent, and have another thread waiting for it, which then sends the message - but it wouldn’t be noticably better than the timer idea, and needs another thread.


#11

I personally doubt that it would lock, but yeah otherwise it is a “black box”…


#12

Well. Thanks a lot for all the answers.

I’ll maybe use some custom stuff then…


#13

What about my suggestion:

[quote]Why not just add a “ID” integer to the Component class plus another integer that the programmer can use for his purposes?
This way the programmer could assign an id to the component. The realtime thread would just call a function, such as setComponentValue(int id, float value) and the rest would be done with a big switch. The second integer could be used as a redraw flag for instance and so the programmer could install a Timer that checks all components he wants for the flag and call repaint() in another Thread than the DSP thread.
This is at least how I did the whole thing in my apps. But this also forced me to rewrite all sliders, buttons, …
If the 2 integers would be there in Component, this would make life much easier sometimes.[/quote]

I would also be very nice to have a function to get the Component pointer via the ID.


#14

[quote=“zamrate”]Why not just add a “ID” integer to the Component class plus another integer that the programmer can use for his purposes?
This way the programmer could assign an id to the component. The realtime thread would just call a function, such as setComponentValue(int id, float value) and the rest would be done with a big switch. The second integer could be used as a redraw flag for instance and so the programmer could install a Timer that checks all components he wants for the flag and call repaint() in another Thread than the DSP thread.
This is at least how I did the whole thing in my apps. But this also forced me to rewrite all sliders, buttons, …
If the 2 integers would be there in Component, this would make life much easier sometimes.[/quote]

Each time I see a big switch, I immediately think about the nightmare it will be to maintain such a beast sooner or later. Especially if the number of case statements is likely to change.


#15

The best way when I think of it, is to have a lock-free FIFO (which is preallocated) which then is monitored by a thread that picks the items, converts to messages and posts to the main GUI thread. That way all parts of RT that need anything done just posts to the FIFO (without any lock).


#16

I have done recently exactly what robiwan suggested.

After that, I thank about a more general (juce speaking) solution : creating a custom allocator for the Message class (i.e. redefining new and delete operators for this class).

This idea behind this is that postMessage is central to the juce API (ChangeBroadcaster, setXXX on a component, ect. rely on it) and finding a way to enable all of this features from the real time thread is worth it.

One possibility would be to change the API to use a passed by value message instead of an allocated message, but that would break a lot of code.
On the other hand, writing a custom allocator for Message that would use a pool of buffer, while not completely trivial (that code must be multithread safe) won’t break anything.

A final word: when using Pro Tools on a dual-core with Leopard, a single tiny new() always lead to 9128 errors, so I think this is a severe issue in Juce.


#17

humm interesting.

I had some strange reports of CPU overload in Protools 7.4 only. This is maybe related.
My whole DSP code doesn’t malloc, only those notifications so it might be interesting to check this.

Thanks,


#18

[quote=“mdsp”][quote=“zamrate”]Why not just add a “ID” integer to the Component class plus another integer that the programmer can use for his purposes?
This way the programmer could assign an id to the component. The realtime thread would just call a function, such as setComponentValue(int id, float value) and the rest would be done with a big switch. The second integer could be used as a redraw flag for instance and so the programmer could install a Timer that checks all components he wants for the flag and call repaint() in another Thread than the DSP thread.
This is at least how I did the whole thing in my apps. But this also forced me to rewrite all sliders, buttons, …
If the 2 integers would be there in Component, this would make life much easier sometimes.[/quote]

Each time I see a big switch, I immediately think about the nightmare it will be to maintain such a beast sooner or later. Especially if the number of case statements is likely to change.[/quote]

Well, the original JUCE way is that when I have many buttons in one app, I have to add some ButtonListener(s), and there will be code with many IF’s ELSE’s there. This is even worse than switches, because it is not optimised (switches use look-up tables) and it is by the way not more readable than switches IMHO.
Plus: adding 2 extra user-definable int’s to the Component class is not like really asking much. They could also be used for something else.


#19

+1

i think is better a global unmodifiable componentID assigned by the framework upon creation and a modifiable userDefinedID which the user can set and get deliberately.

also, as previously suggested by zamrate, would be useful to have a function like:

static Component* Component::getComponentByUniqueID (const int componentID)

For the AsyncUpdaterWhichDontMalloc implementation i think what robiwan suggested is a cool addition to the library.
Anyone have a working LockFreeFifo implementation (in the juce style maybe!) that we can use for implementing that class ?


#20

+1

i think is better a global unmodifiable componentID assigned by the framework upon creation and a modifiable userDefinedID which the user can set and get deliberately.[/quote]
JUCE already provides an unmodifiable UID, see Component::getComponenUID(). But another 1 or better 2 user-definable int32’s would be very nice, for whatever purpose.