blob: 194631397ec3caf0542f6355e61f8ea92eef7ab2 [file] [log] [blame]
/*
* Copyright 2008 Sony Corporation of America
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <libspe2.h>
#include <mars/task.h>
#define INFO \
"\
MARS Task Queue Sample \n\
--------------------------- \n\
This program shows the basic usage of the MARS task queue \n\
between the host program and multiple MPU programs. \n\
\n\
This program creates %d instances of 2 task programs and \n\
creates 3 queues. The 3 separate queues are each created \n\
for different directions, host to MPU, MPU to MPU, and \n\
MPU to host. \n\
\n\
The host program first creates and begins all task \n\
instances for execution. It then begins pushing data into \n\
the host to MPU queue for task 1 program to process. \n\
The host pushes %d data entries to each of the %d \n\
instances of task 1 program. \n\
\n\
The task 1 program instances wait for data to arrive from \n\
the host and pop the data as it arrives. After popping \n\
the data, it handles some processing before pushing data \n\
into the MPU to MPU queue for task 2 program to process. \n\
\n\
The task 2 program instances wait for data to arrive from \n\
the first task program and pop the data as it arrives. \n\
After popping the data, it handles some processing before \n\
pushing data into the MPU to host queue for the host program \n\
to receive the resulting data. \n\
\n\
Once the host pops and receives all result data from the \n\
task 2 program, it displays the results and destroys all \n\
task instances. The displayed result shows the path of \n\
processing from host -> task 1 program -> task 2 program. \n\
\n", NUM_TASKS, NUM_ENTRIES, NUM_TASKS
#define NUM_TASKS 3
#define NUM_ENTRIES 10
#define QUEUE_DEPTH (NUM_TASKS * NUM_ENTRIES)
struct queue_entry {
char text[64];
};
extern struct spe_program_handle mpu_task1_prog;
extern struct spe_program_handle mpu_task2_prog;
static struct mars_context *mars_ctx;
static struct mars_task_id task1_id[NUM_TASKS];
static struct mars_task_id task2_id[NUM_TASKS];
static struct mars_task_args task_args;
static uint64_t host_to_mpu_ea;
static uint64_t mpu_to_host_ea;
static uint64_t mpu_to_mpu_ea;
int main(void)
{
struct queue_entry data;
int ret, i;
printf(INFO);
ret = mars_context_create(&mars_ctx, 0, 0);
if (ret) {
printf("MARS context create failed! (%d)\n", ret);
return 1;
}
ret = mars_task_queue_create(mars_ctx, &host_to_mpu_ea,
sizeof(struct queue_entry), QUEUE_DEPTH,
MARS_TASK_QUEUE_HOST_TO_MPU);
if (ret) {
printf("MARS task queue create failed! (%d)\n", ret);
return 1;
}
ret = mars_task_queue_create(mars_ctx, &mpu_to_host_ea,
sizeof(struct queue_entry), QUEUE_DEPTH,
MARS_TASK_QUEUE_MPU_TO_HOST);
if (ret) {
printf("MARS task queue create failed! (%d)\n", ret);
return 1;
}
ret = mars_task_queue_create(mars_ctx, &mpu_to_mpu_ea,
sizeof(struct queue_entry), QUEUE_DEPTH,
MARS_TASK_QUEUE_MPU_TO_MPU);
if (ret) {
printf("MARS task queue create failed! (%d)\n", ret);
return 1;
}
for (i = 0; i < NUM_TASKS; i++) {
char name[MARS_TASK_NAME_LEN_MAX];
snprintf(name, MARS_TASK_NAME_LEN_MAX, "Task 1.%d", i + 1);
ret = mars_task_create(mars_ctx, &task1_id[i], name,
mpu_task1_prog.elf_image, MARS_TASK_CONTEXT_SAVE_SIZE_MAX);
if (ret) {
printf("MARS task 1 create failed! (%d)\n", ret);
return 1;
}
snprintf(name, MARS_TASK_NAME_LEN_MAX, "Task 2.%d", i + 1);
ret = mars_task_create(mars_ctx, &task2_id[i], name,
mpu_task2_prog.elf_image, MARS_TASK_CONTEXT_SAVE_SIZE_MAX);
if (ret) {
printf("MARS task 2 create failed! (%d)\n", ret);
return 1;
}
task_args.type.u64[0] = host_to_mpu_ea;
task_args.type.u64[1] = mpu_to_mpu_ea;
task_args.type.u32[4] = NUM_ENTRIES;
ret = mars_task_schedule(&task1_id[i], &task_args, 0);
if (ret) {
printf("MARS task 1 schedule failed! (%d)\n", ret);
return 1;
}
task_args.type.u64[0] = mpu_to_mpu_ea;
task_args.type.u64[1] = mpu_to_host_ea;
task_args.type.u32[4] = NUM_ENTRIES;
ret = mars_task_schedule(&task2_id[i], &task_args, 0);
if (ret) {
printf("MARS task 2 schedule failed! (%d)\n", ret);
return 1;
}
}
for (i = 0; i < QUEUE_DEPTH; i++) {
sprintf(data.text, "Host Data %d", i + 1);
ret = mars_task_queue_push(host_to_mpu_ea, &data);
if (ret) {
printf("MARS task queue push failed! (%d)\n", ret);
return 1;
}
printf("HOST : Main() - Pushed HOST->MPU queue: '%s'\n", data.text);
}
for (i = 0; i < QUEUE_DEPTH; i++) {
ret = mars_task_queue_pop(mpu_to_host_ea, &data);
if (ret) {
printf("MARS task queue pop failed! (%d)\n", ret);
return 1;
}
printf("HOST : Main() - Popped MPU->HOST queue: '%s'\n", data.text);
}
for (i = 0; i < NUM_TASKS; i++) {
ret = mars_task_wait(&task1_id[i], NULL);
if (ret) {
printf("MARS task 1 wait failed! (%d)\n", ret);
return 1;
}
ret = mars_task_wait(&task2_id[i], NULL);
if (ret) {
printf("MARS task 2 wait failed! (%d)\n", ret);
return 1;
}
ret = mars_task_destroy(&task1_id[i]);
if (ret) {
printf("MARS task 1 destroy failed! (%d)\n", ret);
return 1;
}
ret = mars_task_destroy(&task2_id[i]);
if (ret) {
printf("MARS task 2 destroy failed! (%d)\n", ret);
return 1;
}
}
ret = mars_context_destroy(mars_ctx);
if (ret) {
printf("MARS context destroy failed! (%d)\n", ret);
return 1;
}
return 0;
}