blob: 2387cddb85311ec2e162b275d1ca7f9e6fa0789e [file] [log] [blame]
/**
* Copyright (c) 2015 Runtime Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "os/os.h"
#include "os/queue.h"
#include "console/console.h"
#ifdef SHELL_PRESENT
#include "shell/shell.h"
#endif
#include <string.h>
struct os_task_info_walk {
struct os_task_info *info;
int info_cnt;
};
#define OS_TASK_INFO_NAME_SIZE (32)
struct os_task_info {
uint8_t oti_tid;
uint8_t oti_prio;
uint8_t oti_state;
uint8_t oti_pad1;
uint16_t oti_flags;
uint16_t oti_stack_size;
uint32_t oti_csw_cnt;
os_time_t oti_next_wakeup;
os_time_t oti_run_time;
char oti_name[OS_TASK_INFO_NAME_SIZE];
};
int os_task_info_get(struct os_task_info *info, int info_cnt);
#ifdef SHELL_PRESENT
struct shell_cmd shell_os_tasks_display_cmd;
#endif
#ifdef SHELL_PRESENT
/* Code to register with shell, and display the results of os_getinfo()
*/
int
shell_os_tasks_display(int argc, char **argv)
{
struct os_task_info *info;
char *name;
int i;
int found;
int rc;
uint8_t tcount;
name = NULL;
found = 0;
if (argc > 1 && strcmp(argv[1], "")) {
name = argv[1];
}
tcount = os_task_count();
info = (struct os_task_info *) os_malloc(
sizeof(struct os_task_info) * tcount);
if (!info) {
rc = -1;
goto err;
}
rc = os_task_info_get(info, tcount);
console_printf("%d tasks: \n", rc);
for (i = 0; i < rc; i++) {
if (name) {
if (strcmp(name, info[i].oti_name)) {
continue;
} else {
found = 1;
}
}
console_printf(" %s (prio: %u, nw: %u, flags: 0x%x, "
"ssize: %u, cswcnt: %lu, tot_run_time: %ums)\n",
info[i].oti_name,
info[i].oti_prio, info[i].oti_next_wakeup, info[i].oti_flags,
info[i].oti_stack_size,
info[i].oti_csw_cnt, info[i].oti_run_time);
}
if (name && !found) {
console_printf("Couldn't find task with name %s\n", name);
}
os_free(info);
return (0);
err:
return (rc);
}
#endif
static int
_os_task_copy_info(struct os_task *t, void *arg)
{
struct os_task_info_walk *walk;
walk = (struct os_task_info_walk *) arg;
if (walk->info_cnt == 0) {
/* Stored all the elements we can fit, exit out */
return (1);
}
walk->info->oti_tid = t->t_taskid;
walk->info->oti_prio = t->t_prio;
strncpy(walk->info->oti_name, t->t_name, OS_TASK_INFO_NAME_SIZE);
walk->info->oti_state = (uint8_t) t->t_state;
walk->info->oti_next_wakeup = t->t_next_wakeup;
walk->info->oti_flags = t->t_flags;
walk->info->oti_stack_size = t->t_stacksize;
walk->info->oti_csw_cnt = t->t_ctx_sw_cnt;
walk->info->oti_run_time = t->t_run_time;
walk->info += 1;
walk->info_cnt--;
return (0);
}
int
os_task_info_get(struct os_task_info *info, int info_cnt)
{
struct os_task_info_walk walk;
walk.info = info;
walk.info_cnt = info_cnt;
os_sched_walk(_os_task_copy_info, (void *) &walk);
return (info_cnt - walk.info_cnt);
}
int
os_info_init(void)
{
#ifdef SHELL_PRESENT
shell_cmd_register(&shell_os_tasks_display_cmd, "tasks",
shell_os_tasks_display);
#endif
return (0);
}