blob: 61d83433f3163e063a691ba7f6db70cc9753a96f [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 <unistd.h>
#include <libspe2.h>
#include <mars/task.h>
#define INFO \
"\
MARS Task Unschedule Sample \n\
------------------------ \n\
This program shows the basic example of unscheduling MARS tasks.\n\
Scheduled tasks can be unscheduled from both host and MPU \n\
\n\
This program creates 2 different tasks. One instance of \n\
the first task is created and %d instances of the second \n\
task is created. \n\
\n\
The first task is scheduled for execution by the host. \n\
The first task then schedules %d instances of the second \n\
task for execution using the sub task's id's specified \n\
by the arguments passed in by the host during scheduling. \n\
The task then enters a wait state until sub tasks are finished. \n\
\n\
The first sub task instance enters an infinite yielding loop. \n\
The second sub task instance enters an infinite wait state. \n\
\n\
Both the host and first task are waiting for one of the 2 sub \n\
tasks to complete. Therefore, it is necessary for the host to \n\
unschedule the first sub task so the first task can resume and \n\
unschedule the second sub task so that both host and first task \n\
can resume and complete the sample. \n\
\n", NUM_TASKS, NUM_TASKS
#define NUM_TASKS 2
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;
static struct mars_task_id task2_id[NUM_TASKS] __attribute__((aligned(16)));
static struct mars_task_args task_args;
int main(void)
{
int ret, i, exit_code;
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_create(mars_ctx, &task1_id, "Task 1",
mpu_task1_prog.elf_image, MARS_TASK_CONTEXT_SAVE_SIZE_MAX);
if (ret) {
printf("MARS task 1 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 2.%d", i);
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] = mars_ptr_to_ea(&task2_id[0]);
task_args.type.u64[1] = mars_ptr_to_ea(&task2_id[1]);
ret = mars_task_schedule(&task1_id, &task_args, 0);
if (ret) {
printf("MARS task 1 schedule failed! (%d)\n", ret);
return 1;
}
sleep(1);
printf("HOST : Unscheduling Sub Task 1\n");
ret = mars_task_unschedule(&task2_id[0], 123);
if (ret) {
printf("MARS task 2.0 unschedule failed! (%d)\n", ret);
return 1;
}
printf("HOST : Waiting for Sub Task 2 to finish...\n");
ret = mars_task_wait(&task2_id[1], &exit_code);
if (ret) {
printf("MARS task 2.1 wait failed! (%d)\n", ret);
return 1;
} else if (exit_code) {
printf("HOST : Sub Task 2 returned (exit_code = %d)\n", exit_code);
}
ret = mars_task_wait(&task1_id, NULL);
if (ret) {
printf("MARS task 1 wait failed! (%d)\n", ret);
return 1;
}
ret = mars_task_destroy(&task1_id);
if (ret) {
printf("MARS task 1 destroy failed! (%d)\n", ret);
return 1;
}
for (i = 0; i < NUM_TASKS; i++) {
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;
}