/* Copyright (C) 2008 - Ruben Niederhagen
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you will find it online at
 * http://www.gnu.org/licenses/gpl.html
 */

/**
 * \file
 * \author Ruben Niederhagen (ruben@polycephaly.org)
 */

#ifndef _IOALOS_INCLUDE_PPU_TOOLS_H_
#define _IOALOS_INCLUDE_PPU_TOOLS_H_

#include <libspe2.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/** 
* \brief Handle for internal SPE context.
*/
typedef struct spe_handle spe_handle_t;

/** 
* \brief Initialize SPEs.
*
* This function initializes a number of SPEs. Global as well as individual parameters can be 
* transfered to the SPEs automatically.
*
* SPEs are only initialized but not yet started.
* 
* \param program Program handle of the SPE binary.
* \param spe_threads Number of SPE threads to be started.
* \param globals This data is passed to all SPEs. It must have correct DMA alignment and size.
* \param globals_size Size of global data (globals).
* \param locals Pointer to an array that contains \#spe_threads data elements to be passed to each SPE.
* Data must be aligned properly in a 16byte grid; to achieve this, the size of each data element should
* be a multiple of 16.
* \param locals_size Size of one private data element (not the size of the list...).
* 
* \return A handle for the created SPE threads.
*/
spe_handle_t* init_spes(spe_program_handle_t *program, uint8_t spe_threads, 
								void *globals, uint16_t globals_size,
								void *locals, uint16_t locals_size); 

/** 
* \brief Start SPE threads.
*
* Start a set of SPESs previously initialized via init_spes().
*
* This method is non-blocking! Use join_spes() to wait until all SPE threads have finished.
* 
* \param handle The handle to the SPEs which are to be started. 
*/
void start_spes(spe_handle_t *handle);

/** 
* \brief Wait until all SPEs have finished.
*
* This method pauses execution until all SPE threads have finished. The 
* threads should have been started via start_spes() before.
* 
* \param handle The handle to the SPEs which are to be waited for.
*/
void join_spes(spe_handle_t *handle);

/** 
* \brief Release resources required for the SPEs.
*
* Frees all allocated data structures associated with the given handle.
*
* The SPE threads should have finished before their resources are freed.
* Use join_spes() to wait for running SPE threads.
* 
* \param handle The handle to the SPEs whose resources are to be freed.
*/
void free_spes(spe_handle_t *handle);

#ifdef __cplusplus
}
#endif

#endif /* _IOALOS_INCLUDE_PPU_TOOLS_H */

