source: mainline/kernel/generic/src/ps/ps.c@ 638927a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 638927a was 638927a, checked in by Stanislav Kozina <stanislav.kozina@…>, 15 years ago

top echoes also thread state overview
write_barrier() after computing percentages

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2010 Stanislav Kozina
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genericps
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Process listing.
36 */
37
38#include <proc/task.h>
39#include <proc/thread.h>
40#include <ps/ps.h>
41#include <ps/taskinfo.h>
42#include <adt/avl.h>
43#include <synch/waitq.h>
44#include <syscall/copy.h>
45#include <atomic.h>
46#include <errno.h>
47
48static size_t count;
49static size_t max_count;
50
51#define WRITE_TASK_ID(dst, i, src) copy_to_uspace(dst + i, src, sizeof(task_id_t))
52#define WRITE_THREAD_INFO(dst, i, src) copy_to_uspace(dst+i, src, sizeof(thread_info_t))
53
54static bool task_walker(avltree_node_t *node, void *arg)
55{
56 task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
57 task_id_t *ids = (task_id_t *)arg;
58
59 spinlock_lock(&t->lock);
60
61 ++count;
62 if (count > max_count) {
63 spinlock_unlock(&t->lock);
64 return false;
65 }
66
67 WRITE_TASK_ID(ids, count - 1, &t->taskid);
68
69 spinlock_unlock(&t->lock);
70 return true;
71}
72
73size_t sys_ps_get_tasks(task_id_t *uspace_ids, size_t size)
74{
75 ipl_t ipl;
76
77 /* Messing with task structures, avoid deadlock */
78 ipl = interrupts_disable();
79 spinlock_lock(&tasks_lock);
80
81 count = 0;
82 max_count = size / sizeof(task_id_t);
83 avltree_walk(&tasks_tree, task_walker, uspace_ids);
84
85 spinlock_unlock(&tasks_lock);
86 interrupts_restore(ipl);
87
88 return count;
89}
90
91static uint64_t get_task_memory(as_t *as)
92{
93 mutex_lock(&as->lock);
94
95 size_t result = 0;
96
97 link_t *cur;
98 for (cur = as->as_area_btree.leaf_head.next;
99 cur != &as->as_area_btree.leaf_head; cur = cur->next) {
100 btree_node_t *node;
101
102 node = list_get_instance(cur, btree_node_t, leaf_link);
103
104 unsigned int i;
105 for (i = 0; i < node->keys; i++) {
106 as_area_t *area = node->value[i];
107
108 mutex_lock(&area->lock);
109 result += area->pages;
110 mutex_unlock(&area->lock);
111 }
112 }
113
114 mutex_unlock(&as->lock);
115
116 return result * PAGE_SIZE;
117}
118
119int sys_ps_get_task_info(task_id_t *uspace_id, task_info_t *uspace_info)
120{
121 ipl_t ipl;
122 ipl = interrupts_disable();
123
124 task_id_t id;
125 copy_from_uspace(&id, uspace_id, sizeof(task_id_t));
126
127 spinlock_lock(&tasks_lock);
128 task_t *t = task_find_by_id(id);
129 if (!t) {
130 spinlock_unlock(&tasks_lock);
131 return ENOENT;
132 }
133 spinlock_lock(&t->lock);
134 spinlock_unlock(&tasks_lock);
135
136 copy_to_uspace(&uspace_info->taskid, &t->taskid, sizeof(task_id_t));
137 copy_to_uspace(uspace_info->name, t->name, sizeof(t->name));
138
139 uint64_t ucycles;
140 uint64_t kcycles;
141 task_get_accounting(t, &ucycles, &kcycles);
142 copy_to_uspace(&uspace_info->ucycles, &ucycles, sizeof(uint64_t));
143 copy_to_uspace(&uspace_info->kcycles, &kcycles, sizeof(uint64_t));
144
145 uint64_t memory = get_task_memory(t->as);
146 copy_to_uspace(&uspace_info->virt_mem, &memory, sizeof(memory));
147
148 int thread_count = atomic_get(&t->refcount);
149 copy_to_uspace(&uspace_info->thread_count, &thread_count, sizeof(thread_count));
150
151 spinlock_unlock(&t->lock);
152 interrupts_restore(ipl);
153 return 0;
154}
155
156static bool thread_walker(avltree_node_t *node, void *arg)
157{
158 thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
159 thread_info_t *infos = (thread_info_t *)arg;
160 thread_info_t result;
161
162 spinlock_lock(&t->lock);
163
164 ++count;
165 if (count > max_count) {
166 spinlock_unlock(&t->lock);
167 return false;
168 }
169
170 result.tid = t->tid;
171 ASSERT(t->task);
172 result.taskid = t->task->taskid;
173 result.state = t->state;
174 result.priority = t->priority;
175 result.ucycles = t->ucycles;
176 result.kcycles = t->kcycles;
177
178 if (t->cpu)
179 result.cpu = t->cpu->id;
180 else
181 result.cpu = -1;
182
183 WRITE_THREAD_INFO(infos, count - 1, &result);
184
185 spinlock_unlock(&t->lock);
186 return true;
187}
188
189int sys_ps_get_threads(thread_info_t *uspace_infos, size_t size)
190{
191 ipl_t ipl;
192 ipl = interrupts_disable();
193 spinlock_lock(&threads_lock);
194
195 count = 0;
196 max_count = size / sizeof(thread_info_t);
197 avltree_walk(&threads_tree, thread_walker, uspace_infos);
198
199 spinlock_unlock(&threads_lock);
200 interrupts_restore(ipl);
201 return count;
202}
203
204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.