/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss of reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#include "coop.h"

/** @addtogroup coop_event */
/** @{ */

/**
*	Post one or more event(s).
*
*	The function delivers one or more events to a process. The event(s) will
*	be added to the pending events of the process and this function returns
*	immediately. This function can be called from an interrupt routine.
*
*	If the events to post contain events that are reserved for kernel internal
*	operations (i.e. they have a bit position BZ_EVENT_MAX or larger), these
*	will be deleted from the event set.
*
*	@param	pid		The ID of the process to send the events to.
*					If the pid is BZ_PID_BCAST then the event(s) will be
*					delivered to every thread.
*
*	@param	event	The bit mask of the event(s) to post.
*
*	@retval	BZ_ILLEGAL_PID	The specified process does not exist.
*	@retval	0				Success.
*/

int		BZ_EventPost( int pid, int event )
{
	return( _bz_EventPost( pid, event & ( ( 1 << BZ_EVENT_MAX ) - 1 ) ) );
}

/** @} */

/****************************************************************************/
/****************************************************************************/

int		_bz_EventPost( unsigned pid, int event )
{
BZ_STAT	*base;
int		stat;

	base   = &_bz_stat;
	event |= BZ_EVENT_ALWAYS;

	if ( pid >= base->maxp && pid != 255 ) return( BZ_ILLEGAL_PID );

	stat = BZ_IrqDisable( 1 );
	base->flag  = 1;

	if ( pid == 255  ) {

		// Broadcast, post the event to all threads.

		for ( pid = base->maxp - 1 ; pid  ; pid-- )

			base->proc[ pid ].sigs |= event;
	}

	base->proc[ pid ].sigs |= event;
	BZ_IrqDisable( stat );
	return( 0 );
}

