/* * Copyright (C) 2013 Philippe Gerum . * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include #include #include #include #include #include #include #include #include "sysregfs.h" #include "../internal.h" #ifdef CONFIG_XENO_PSHARED static int retrieve_task_state(pid_t pid) { char trash[BUFSIZ], state = '?', path[32]; FILE *fp; int ret; /* * Try to figure out the state in kernel context of a Mercury * task which does not wait on a copperplate service. If this * task is not runnable, then display 'X', which is * reminiscent of a Cobalt task running out of real-time mode. * Otherwise, show this task as runnable. */ snprintf(path, sizeof(path), "/proc/%d/stat", pid); fp = fopen(path, "r"); if (fp) { ret = fscanf(fp, "%[0-9] (%[^) ]) %c", trash, trash, &state); fclose(fp); if (ret == 3 && state != 'R') state = 'X'; } return state; } char *format_thread_status(const struct thread_data *p, char *buf, size_t len) { char *wp = buf; if (len < 4) return NULL; if (p->status & __THREAD_S_TIMEDWAIT) *wp++ = 'w'; else if (p->status & __THREAD_S_WAIT) *wp++ = 'W'; else if (p->status & __THREAD_S_DELAYED) *wp++ = 'D'; else if (p->status & __THREAD_S_STARTED) *wp++ = retrieve_task_state(p->pid); else *wp++ = 'U'; if (p->schedlock > 0) *wp++ = 'l'; if (p->policy == SCHED_RR) *wp++ = 'r'; *wp = '\0'; return buf; } #endif /* CONFIG_XENO_PSHARED */ struct sysreg_fsdir sysreg_dirs[] = { { .path = NULL, }, }; struct sysreg_fsfile sysreg_files[] = { #ifdef CONFIG_XENO_PSHARED { .path = "/threads", .mode = O_RDONLY, .ops = { .open = open_threads, .release = fsobj_obstack_release, .read = fsobj_obstack_read }, }, { .path = "/heaps", .mode = O_RDONLY, .ops = { .open = open_heaps, .release = fsobj_obstack_release, .read = fsobj_obstack_read }, }, #endif /* CONFIG_XENO_PSHARED */ { .path = "/version", .mode = O_RDONLY, .ops = { .open = open_version, .release = fsobj_obstack_release, .read = fsobj_obstack_read }, }, { .path = NULL, } };