Changeset 80bfb601 in mainline
- Timestamp:
- 2010-04-18T09:57:19Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d869398
- Parents:
- fce3536
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/sysinfo/abi.h
rfce3536 r80bfb601 31 31 */ 32 32 /** @file 33 * Data structures passed between kernel sysinfo and user space. 33 34 */ 34 35 … … 36 37 #define KERN_ABI_H_ 37 38 39 /** Number of load components */ 38 40 #define LOAD_STEPS 3 41 42 /** Maximum task name size */ 39 43 #define TASK_NAME_BUFLEN 20 40 44 45 /** Statistics about a single CPU 46 * 47 */ 41 48 typedef struct { 42 unsigned int id; 43 uint16_t frequency_mhz; 44 uint64_t idle_ticks; 45 uint64_t busy_ticks; 49 unsigned int id; /**< CPU ID as stored by kernel */ 50 uint16_t frequency_mhz; /**< Frequency in MHz */ 51 uint64_t idle_ticks; /**< Number of idle kernel quanta */ 52 uint64_t busy_ticks; /**< Number of busy kernel quanta */ 46 53 } stats_cpu_t; 47 54 55 /** Physical memory statistics 56 * 57 */ 48 58 typedef struct { 49 uint64_t total; 50 uint64_t unavail; 51 uint64_t used; 52 uint64_t free; 59 uint64_t total; /**< Total physical memory (bytes) */ 60 uint64_t unavail; /**< Unavailable (reserved, firmware) bytes */ 61 uint64_t used; /**< Allocated physical memory (bytes) */ 62 uint64_t free; /**< Free physical memory (bytes) */ 53 63 } stats_physmem_t; 54 64 65 /** IPC statistics 66 * 67 * Associated with a task. 68 * 69 */ 55 70 typedef struct { 56 uint64_t call_sent; 57 uint64_t call_recieved; 58 uint64_t answer_sent; 59 uint64_t answer_recieved; 60 uint64_t irq_notif_recieved; 61 uint64_t forwarded; 71 uint64_t call_sent; /**< IPC calls sent */ 72 uint64_t call_recieved; /**< IPC calls received */ 73 uint64_t answer_sent; /**< IPC answers sent */ 74 uint64_t answer_recieved; /**< IPC answers received */ 75 uint64_t irq_notif_recieved; /**< IPC IRQ notifications */ 76 uint64_t forwarded; /**< IPC messages forwarded */ 62 77 } stats_ipc_t; 63 78 79 /** Statistics about a single task 80 * 81 */ 64 82 typedef struct { 65 char name[TASK_NAME_BUFLEN]; 66 size_t virtmem; 67 size_t threads; 68 uint64_t ucycles; 69 uint64_t kcycles; 70 stats_ipc_t ipc_info; 83 char name[TASK_NAME_BUFLEN]; /**< Task name (in kernel) */ 84 size_t virtmem; /**< Size of VAS (bytes) */ 85 size_t threads; /**< Number of threads */ 86 uint64_t ucycles; /**< Number of CPU cycles in user space */ 87 uint64_t kcycles; /**< Number of CPU cycles in kernel */ 88 stats_ipc_t ipc_info; /**< IPC statistics */ 71 89 } stats_task_t; 72 90 91 /** Load fixed-point value */ 73 92 typedef uint32_t load_t; 74 93 -
kernel/generic/include/sysinfo/sysinfo.h
rfce3536 r80bfb601 39 39 #include <str.h> 40 40 41 /** Framebuffer info exported flags */ 41 42 extern bool fb_exported; 42 43 44 /** Item value type 45 * 46 */ 43 47 typedef enum { 44 SYSINFO_VAL_UNDEFINED = 0, 45 SYSINFO_VAL_VAL = 1, 46 SYSINFO_VAL_DATA = 2, 47 SYSINFO_VAL_FUNCTION_VAL = 3, 48 SYSINFO_VAL_FUNCTION_DATA = 4 48 SYSINFO_VAL_UNDEFINED = 0, /**< Undefined value */ 49 SYSINFO_VAL_VAL = 1, /**< Constant numeric value */ 50 SYSINFO_VAL_DATA = 2, /**< Constant binary data */ 51 SYSINFO_VAL_FUNCTION_VAL = 3, /**< Generated numeric value */ 52 SYSINFO_VAL_FUNCTION_DATA = 4 /**< Generated binary data */ 49 53 } sysinfo_item_val_type_t; 50 54 55 /** Subtree type 56 * 57 */ 51 58 typedef enum { 52 SYSINFO_SUBTREE_NONE = 0, 53 SYSINFO_SUBTREE_TABLE = 1, 54 SYSINFO_SUBTREE_FUNCTION = 2 59 SYSINFO_SUBTREE_NONE = 0, /**< No subtree (leaf item) */ 60 SYSINFO_SUBTREE_TABLE = 1, /**< Fixed subtree */ 61 SYSINFO_SUBTREE_FUNCTION = 2 /**< Generated subtree */ 55 62 } sysinfo_subtree_type_t; 56 63 57 64 struct sysinfo_item; 58 65 66 /** Gerated numeric value function */ 59 67 typedef unative_t (*sysinfo_fn_val_t)(struct sysinfo_item *); 68 69 /** Generated binary data function */ 60 70 typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *); 61 71 72 /** Sysinfo item binary data 73 * 74 */ 62 75 typedef struct { 63 void *data; 64 size_t size; 76 void *data; /**< Data */ 77 size_t size; /**< Size (bytes) */ 65 78 } sysinfo_data_t; 66 79 80 /** Sysinfo item value (union) 81 * 82 */ 67 83 typedef union { 68 unative_t val; 69 sysinfo_fn_val_t fn_val; 70 sysinfo_fn_data_t fn_data; 71 sysinfo_data_t data; 84 unative_t val; /**< Constant numberic value */ 85 sysinfo_fn_val_t fn_val; /**< Generated numeric value function */ 86 sysinfo_fn_data_t fn_data; /**< Generated binary data function */ 87 sysinfo_data_t data; /**< Constant binary data */ 72 88 } sysinfo_item_val_t; 73 89 90 /** Sysinfo return holder 91 * 92 * This structure is generated from the constant 93 * items or by the generating functions. Note that 94 * the validity of the data is limited by the scope 95 * of single sysinfo invocation guarded by sysinfo_lock. 96 * 97 */ 74 98 typedef struct { 75 sysinfo_item_val_type_t tag; 99 sysinfo_item_val_type_t tag; /**< Return value type */ 76 100 union { 77 unative_t val; 78 sysinfo_data_t data; 101 unative_t val; /**< Numberic value */ 102 sysinfo_data_t data; /**< Binary data */ 79 103 }; 80 104 } sysinfo_return_t; 81 105 106 /** Generated subtree function */ 82 107 typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *); 83 108 109 /** Sysinfo subtree (union) 110 * 111 */ 84 112 typedef union { 85 struct sysinfo_item *table; 86 sysinfo_fn_subtree_t get_data; 113 struct sysinfo_item *table; /**< Fixed subtree (list of subitems) */ 114 sysinfo_fn_subtree_t get_data; /**< Generated subtree function */ 87 115 } sysinfo_subtree_t; 88 116 117 /** Sysinfo item 118 * 119 */ 89 120 typedef struct sysinfo_item { 90 char *name; 121 char *name; /**< Item name */ 91 122 92 sysinfo_item_val_type_t val_type; 93 sysinfo_item_val_t val; 123 sysinfo_item_val_type_t val_type; /**< Item value type */ 124 sysinfo_item_val_t val; /**< Item value */ 94 125 95 sysinfo_subtree_type_t subtree_type; 96 sysinfo_subtree_t subtree; 126 sysinfo_subtree_type_t subtree_type; /**< Subtree type */ 127 sysinfo_subtree_t subtree; /**< Subtree */ 97 128 98 struct sysinfo_item *next; 129 struct sysinfo_item *next; /**< Sibling item */ 99 130 } sysinfo_item_t; 100 131 … … 114 145 extern void sysinfo_dump(sysinfo_item_t *); 115 146 116 unative_t sys_sysinfo_get_tag(void *, size_t);117 unative_t sys_sysinfo_get_value(void *, size_t, void *);118 unative_t sys_sysinfo_get_data_size(void *, size_t, void *);119 unative_t sys_sysinfo_get_data(void *, size_t, void *, size_t);147 extern unative_t sys_sysinfo_get_tag(void *, size_t); 148 extern unative_t sys_sysinfo_get_value(void *, size_t, void *); 149 extern unative_t sys_sysinfo_get_data_size(void *, size_t, void *); 150 extern unative_t sys_sysinfo_get_data(void *, size_t, void *, size_t); 120 151 121 152 #endif -
kernel/generic/src/sysinfo/stats.c
rfce3536 r80bfb601 55 55 #define LOAD_INTERVAL 5 56 56 57 /** 58 * Fixed-point representation of: 57 /** Fixed-point representation of 59 58 * 60 59 * 1 / exp(5 sec / 1 min) … … 64 63 */ 65 64 static load_t load_exp[LOAD_STEPS] = {1884, 2014, 2037}; 65 66 /** Running average of the number of ready threads */ 66 67 static load_t avenrdy[LOAD_STEPS] = {0, 0, 0}; 68 69 /** Load calculation spinlock */ 67 70 SPINLOCK_STATIC_INITIALIZE_NAME(load_lock, "load_lock"); 68 71 72 /** Get system uptime 73 * 74 * @param item Sysinfo item (unused). 75 * 76 * @return System uptime (in secords). 77 * 78 */ 69 79 static unative_t get_stats_uptime(struct sysinfo_item *item) 70 80 { … … 73 83 } 74 84 85 /** Get statistics of all CPUs 86 * 87 * @param item Sysinfo item (unused). 88 * @param size Size of the returned data. 89 * 90 * @return Data containing several stats_cpu_t structures. 91 * If the return value is not NULL, it should be freed 92 * in the context of the sysinfo request. 93 */ 75 94 static void *get_stats_cpus(struct sysinfo_item *item, size_t *size) 76 95 { 96 /* Assumption: config.cpu_count is constant */ 77 97 stats_cpu_t *stats_cpus = 78 98 (stats_cpu_t *) malloc(sizeof(stats_cpu_t) * config.cpu_count, … … 83 103 } 84 104 105 /* Each CPU structure is locked separatelly */ 85 106 ipl_t ipl = interrupts_disable(); 86 107 … … 103 124 } 104 125 126 /** Count number of tasks 127 * 128 * AVL task tree walker for counting tasks. 129 * 130 * @param node AVL task tree node (unused). 131 * @param arg Pointer to the counter. 132 * 133 * @param Always true (continue the walk). 134 * 135 */ 105 136 static bool task_count_walker(avltree_node_t *node, void *arg) 106 137 { … … 111 142 } 112 143 144 /** Gather tasks 145 * 146 * AVL task tree walker for gathering task IDs. Interrupts should 147 * be already disabled while walking the tree. 148 * 149 * @param node AVL task tree node. 150 * @param arg Pointer to the iterator into the array of task IDs. 151 * 152 * @param Always true (continue the walk). 153 * 154 */ 113 155 static bool task_serialize_walker(avltree_node_t *node, void *arg) 114 156 { … … 116 158 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node); 117 159 160 /* Interrupts are already disabled */ 118 161 spinlock_lock(&(task->lock)); 119 162 163 /* Record the ID and increment the iterator */ 120 164 **ids = task->taskid; 121 165 (*ids)++; … … 126 170 } 127 171 172 /** Get task IDs 173 * 174 * @param item Sysinfo item (unused). 175 * @param size Size of the returned data. 176 * 177 * @return Data containing task IDs of all tasks. 178 * If the return value is not NULL, it should be freed 179 * in the context of the sysinfo request. 180 */ 128 181 static void *get_stats_tasks(struct sysinfo_item *item, size_t *size) 129 182 { … … 132 185 spinlock_lock(&tasks_lock); 133 186 187 /* First walk the task tree to count the tasks */ 134 188 size_t count = 0; 135 189 avltree_walk(&tasks_tree, task_count_walker, (void *) &count); 136 190 137 191 if (count == 0) { 192 /* No tasks found (strange) */ 138 193 spinlock_unlock(&tasks_lock); 139 194 interrupts_restore(ipl); … … 146 201 (task_id_t *) malloc(sizeof(task_id_t) * count, FRAME_ATOMIC); 147 202 if (task_ids == NULL) { 203 /* No free space for allocation */ 148 204 spinlock_unlock(&tasks_lock); 149 205 interrupts_restore(ipl); … … 153 209 } 154 210 211 /* Walk tha task tree again to gather the IDs */ 155 212 task_id_t *iterator = task_ids; 156 213 avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator); … … 163 220 } 164 221 222 /** Get the size of a virtual address space 223 * 224 * @param as Address space. 225 * 226 * @return Size of the mapped virtual address space (bytes). 227 * 228 */ 165 229 static size_t get_task_virtmem(as_t *as) 166 230 { … … 169 233 size_t result = 0; 170 234 235 /* Walk the B+ tree and count pages */ 171 236 link_t *cur; 172 237 for (cur = as->as_area_btree.leaf_head.next; … … 190 255 } 191 256 257 /** Get task statistics 258 * 259 * Get statistics of a given task. The task ID is passed 260 * as a string (current limitation of the sysinfo interface, 261 * but it is still reasonable for the given purpose). 262 * 263 * @param name Task ID (string-encoded number). 264 * 265 * @return Sysinfo return holder. The type of the returned 266 * data is either SYSINFO_VAL_UNDEFINED (unknown 267 * task ID or memory allocation error) or 268 * SYSINFO_VAL_FUNCTION_DATA (in that case the 269 * generated data should be freed within the 270 * sysinfo request context). 271 * 272 */ 192 273 static sysinfo_return_t get_stats_task(const char *name) 193 274 { 194 275 /* Initially no return value */ 195 276 sysinfo_return_t ret; 196 277 ret.tag = SYSINFO_VAL_UNDEFINED; 197 278 279 /* Parse the task ID */ 198 280 task_id_t task_id; 199 281 if (str_uint64(name, NULL, 0, true, &task_id) != EOK) 200 282 return ret; 201 283 284 /* Allocate stats_task_t structure */ 202 285 stats_task_t *stats_task = 203 286 (stats_task_t *) malloc(sizeof(stats_task_t), FRAME_ATOMIC); … … 205 288 return ret; 206 289 290 /* Messing with task structures, avoid deadlock */ 207 291 ipl_t ipl = interrupts_disable(); 208 292 spinlock_lock(&tasks_lock); … … 210 294 task_t *task = task_find_by_id(task_id); 211 295 if (task == NULL) { 296 /* No task with this ID */ 212 297 spinlock_unlock(&tasks_lock); 213 298 interrupts_restore(ipl); … … 216 301 } 217 302 303 /* Hand-over-hand locking */ 218 304 spinlock_lock(&task->lock); 219 305 spinlock_unlock(&tasks_lock); 220 306 307 /* Copy task's statistics */ 221 308 str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name); 222 309 stats_task->virtmem = get_task_virtmem(task->as); … … 229 316 interrupts_restore(ipl); 230 317 318 /* Correct return value */ 231 319 ret.tag = SYSINFO_VAL_FUNCTION_DATA; 232 320 ret.data.data = (void *) stats_task; … … 236 324 } 237 325 326 /** Get physical memory statistics 327 * 328 * @param item Sysinfo item (unused). 329 * @param size Size of the returned data. 330 * 331 * @return Data containing stats_physmem_t. 332 * If the return value is not NULL, it should be freed 333 * in the context of the sysinfo request. 334 */ 238 335 static void *get_stats_physmem(struct sysinfo_item *item, size_t *size) 239 336 { … … 252 349 } 253 350 351 /** Get system load 352 * 353 * @param item Sysinfo item (unused). 354 * @param size Size of the returned data. 355 * 356 * @return Data several load_t values. 357 * If the return value is not NULL, it should be freed 358 * in the context of the sysinfo request. 359 */ 254 360 static void *get_stats_load(struct sysinfo_item *item, size_t *size) 255 361 { … … 261 367 } 262 368 369 /* To always get consistent values acquire the spinlock */ 263 370 ipl_t ipl = interrupts_disable(); 264 371 spinlock_lock(&load_lock); … … 324 431 325 432 while (true) { 433 /* Mutually exclude with get_stats_load() */ 326 434 ipl_t ipl = interrupts_disable(); 327 435 spinlock_lock(&load_lock); … … 340 448 } 341 449 450 /** Register sysinfo statistical items 451 * 452 */ 342 453 void stats_init(void) 343 454 { -
kernel/generic/src/sysinfo/sysinfo.c
rfce3536 r80bfb601 41 41 #include <errno.h> 42 42 43 /** Maximal sysinfo path length */ 43 44 #define SYSINFO_MAX_PATH 2048 44 45 45 46 bool fb_exported = false; 46 47 48 /** Global sysinfo tree root item */ 47 49 static sysinfo_item_t *global_root = NULL; 50 51 /** Sysinfo SLAB cache */ 48 52 static slab_cache_t *sysinfo_item_slab; 49 53 54 /** Sysinfo spinlock */ 50 55 SPINLOCK_STATIC_INITIALIZE_NAME(sysinfo_lock, "sysinfo_lock"); 51 56 57 /** Sysinfo item constructor 58 * 59 */ 52 60 static int sysinfo_item_constructor(void *obj, int kmflag) 53 61 { … … 63 71 } 64 72 73 /** Sysinfo item destructor 74 * 75 * Note that the return value is not perfectly correct 76 * since more space might get actually freed thanks 77 * to the disposal of item->name 78 * 79 */ 65 80 static int sysinfo_item_destructor(void *obj) 66 81 { … … 73 88 } 74 89 90 /** Initialize sysinfo subsystem 91 * 92 * Create SLAB cache for sysinfo items. 93 * 94 */ 75 95 void sysinfo_init(void) 76 96 { … … 80 100 } 81 101 82 /** Recursively find item in sysinfo tree102 /** Recursively find an item in sysinfo tree 83 103 * 84 104 * Should be called with interrupts disabled 85 105 * and sysinfo_lock held. 86 106 * 107 * @param name Current sysinfo path suffix. 108 * @param subtree Current sysinfo (sub)tree root item. 109 * @param ret If the return value is NULL, this argument 110 * can be either also NULL (i.e. no item was 111 * found and no data was generated) or the 112 * original pointer is used to store the value 113 * generated by a generated subtree function. 114 * 115 * @return Found item or NULL if no item in the fixed tree 116 * was found (N.B. ret). 117 * 87 118 */ 88 119 static sysinfo_item_t *sysinfo_find_item(const char *name, … … 94 125 sysinfo_item_t *cur = subtree; 95 126 127 /* Walk all siblings */ 96 128 while (cur != NULL) { 97 129 size_t i = 0; … … 118 150 return NULL; 119 151 default: 120 /* Not found */152 /* Not found, no data generated */ 121 153 *ret = NULL; 122 154 return NULL; … … 127 159 } 128 160 161 /* Not found, no data generated */ 129 162 *ret = NULL; 130 163 return NULL; … … 135 168 * Should be called with interrupts disabled 136 169 * and sysinfo_lock held. 170 * 171 * @param name Current sysinfo path suffix. 172 * @param psubtree Pointer to an already existing (sub)tree root 173 * item or where to store a new tree root item. 174 * 175 * @return Existing or newly allocated sysinfo item or NULL 176 * if the current tree configuration does not allow to 177 * create a new item. 137 178 * 138 179 */ … … 172 213 sysinfo_item_t *cur = *psubtree; 173 214 215 /* Walk all siblings */ 174 216 while (cur != NULL) { 175 217 size_t i = 0; … … 199 241 default: 200 242 /* Subtree items handled by a function, this 201 * cannot be overriden .243 * cannot be overriden by a constant item. 202 244 */ 203 245 return NULL; … … 235 277 } 236 278 237 /* Get next sibling */238 279 cur = cur->next; 239 280 } … … 244 285 } 245 286 287 /** Set sysinfo item with a constant numeric value 288 * 289 * @param name Sysinfo path. 290 * @param root Pointer to the root item or where to store 291 * a new root item (NULL for global sysinfo root). 292 * @param val Value to store in the item. 293 * 294 */ 246 295 void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, 247 296 unative_t val) 248 297 { 298 /* Protect sysinfo tree consistency */ 249 299 ipl_t ipl = interrupts_disable(); 250 300 spinlock_lock(&sysinfo_lock); … … 263 313 } 264 314 315 /** Set sysinfo item with a constant binary data 316 * 317 * Note that sysinfo only stores the pointer to the 318 * binary data and does not touch it in any way. The 319 * data should be static and immortal. 320 * 321 * @param name Sysinfo path. 322 * @param root Pointer to the root item or where to store 323 * a new root item (NULL for global sysinfo root). 324 * @param data Binary data. 325 * @param size Size of the binary data. 326 * 327 */ 265 328 void sysinfo_set_item_data(const char *name, sysinfo_item_t **root, 266 329 void *data, size_t size) 267 330 { 331 /* Protect sysinfo tree consistency */ 268 332 ipl_t ipl = interrupts_disable(); 269 333 spinlock_lock(&sysinfo_lock); … … 283 347 } 284 348 349 /** Set sysinfo item with a generated numeric value 350 * 351 * @param name Sysinfo path. 352 * @param root Pointer to the root item or where to store 353 * a new root item (NULL for global sysinfo root). 354 * @param fn Numeric value generator function. 355 * 356 */ 285 357 void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root, 286 358 sysinfo_fn_val_t fn) 287 359 { 360 /* Protect sysinfo tree consistency */ 288 361 ipl_t ipl = interrupts_disable(); 289 362 spinlock_lock(&sysinfo_lock); … … 302 375 } 303 376 377 /** Set sysinfo item with a generated binary data 378 * 379 * Note that each time the generator function is called 380 * it is supposed to return a new dynamically allocated 381 * data. This data is then freed by sysinfo in the context 382 * of the current sysinfo request. 383 * 384 * @param name Sysinfo path. 385 * @param root Pointer to the root item or where to store 386 * a new root item (NULL for global sysinfo root). 387 * @param fn Binary data generator function. 388 * 389 */ 304 390 void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root, 305 391 sysinfo_fn_data_t fn) 306 392 { 393 /* Protect sysinfo tree consistency */ 307 394 ipl_t ipl = interrupts_disable(); 308 395 spinlock_lock(&sysinfo_lock); … … 321 408 } 322 409 410 /** Set sysinfo item with an undefined value 411 * 412 * @param name Sysinfo path. 413 * @param root Pointer to the root item or where to store 414 * a new root item (NULL for global sysinfo root). 415 * 416 */ 323 417 void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root) 324 418 { 419 /* Protect sysinfo tree consistency */ 325 420 ipl_t ipl = interrupts_disable(); 326 421 spinlock_lock(&sysinfo_lock); … … 337 432 } 338 433 434 /** Set sysinfo item with a generated subtree 435 * 436 * @param name Sysinfo path. 437 * @param root Pointer to the root item or where to store 438 * a new root item (NULL for global sysinfo root). 439 * @param fn Subtree generator function. 440 * 441 */ 339 442 void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root, 340 443 sysinfo_fn_subtree_t fn) 341 444 { 445 /* Protect sysinfo tree consistency */ 342 446 ipl_t ipl = interrupts_disable(); 343 447 spinlock_lock(&sysinfo_lock); … … 347 451 348 452 sysinfo_item_t *item = sysinfo_create_path(name, root); 453 454 /* Change the type of the subtree only if it is not already 455 a fixed subtree */ 349 456 if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) { 350 457 item->subtree_type = SYSINFO_SUBTREE_FUNCTION; … … 357 464 358 465 /** Sysinfo dump indentation helper routine 466 * 467 * @param depth Number of indentation characters to print. 359 468 * 360 469 */ … … 374 483 * there is no better simple solution. 375 484 * 485 * @param root Root item of the current (sub)tree. 486 * @param depth Current depth in the sysinfo tree. 487 * 376 488 */ 377 489 static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth) … … 379 491 sysinfo_item_t *cur = root; 380 492 493 /* Walk all siblings */ 381 494 while (cur != NULL) { 382 495 sysinfo_indent(depth); … … 386 499 size_t size; 387 500 501 /* Display node value and type */ 388 502 switch (cur->val_type) { 389 503 case SYSINFO_VAL_UNDEFINED: … … 405 519 case SYSINFO_VAL_FUNCTION_DATA: 406 520 data = cur->val.fn_data(cur, &size); 521 522 /* N.B.: The generated binary data should be freed */ 407 523 if (data != NULL) 408 524 free(data); … … 415 531 } 416 532 533 /* Recursivelly nest into the subtree */ 417 534 switch (cur->subtree_type) { 418 535 case SYSINFO_SUBTREE_NONE: … … 434 551 } 435 552 553 /** Dump the structure of sysinfo tree 554 * 555 * @param root Root item of the sysinfo (sub)tree. 556 * If it is NULL then consider the global 557 * sysinfo tree. 558 * 559 */ 436 560 void sysinfo_dump(sysinfo_item_t *root) 437 561 { 562 /* Avoid other functions to mess with sysinfo 563 while we are dumping it */ 438 564 ipl_t ipl = interrupts_disable(); 439 565 spinlock_lock(&sysinfo_lock); … … 448 574 } 449 575 450 /** Return sysinfo item determined by name576 /** Return sysinfo item value determined by name 451 577 * 452 578 * Should be called with interrupts disabled 453 579 * and sysinfo_lock held. 454 580 * 581 * @param name Sysinfo path. 582 * @param root Root item of the sysinfo (sub)tree. 583 * If it is NULL then consider the global 584 * sysinfo tree. 585 * 586 * @return Item value (constant or generated). 587 * 455 588 */ 456 589 static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root) … … 459 592 root = &global_root; 460 593 594 /* Try to find the item or generate data */ 461 595 sysinfo_return_t ret; 462 596 sysinfo_return_t *ret_ptr = &ret; … … 464 598 465 599 if (item != NULL) { 600 /* Item found in the fixed sysinfo tree */ 601 466 602 ret.tag = item->val_type; 467 603 switch (item->val_type) { … … 482 618 } 483 619 } else { 484 if (ret_ptr == NULL) 620 /* No item in the fixed sysinfo tree */ 621 if (ret_ptr == NULL) { 622 /* Even no data was generated */ 485 623 ret.tag = SYSINFO_VAL_UNDEFINED; 624 } 486 625 } 487 626 … … 492 631 * 493 632 * Should be called with interrupts disabled 494 * and sysinfo_lock held. 633 * and sysinfo_lock held. The path string passed from 634 * the user space has to be properly null-terminated 635 * (the last passed character must be null). 636 * 637 * @param ptr Sysinfo path in the user address space. 638 * @param size Size of the path string. 495 639 * 496 640 */ … … 514 658 } 515 659 660 /** Get the sysinfo value type (syscall) 661 * 662 * The path string passed from the user space has 663 * to be properly null-terminated (the last passed 664 * character must be null). 665 * 666 * @param path_ptr Sysinfo path in the user address space. 667 * @param path_size Size of the path string. 668 * 669 * @return Item value type. 670 * 671 */ 516 672 unative_t sys_sysinfo_get_tag(void *path_ptr, size_t path_size) 517 673 { 518 ipl_t ipl = interrupts_disable(); 519 spinlock_lock(&sysinfo_lock); 520 674 /* Avoid other functions to mess with sysinfo 675 while we are reading it */ 676 ipl_t ipl = interrupts_disable(); 677 spinlock_lock(&sysinfo_lock); 678 679 /* Get the item */ 521 680 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 522 681 682 /* N.B.: The generated binary data should be freed */ 523 683 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 524 684 free(ret.data.data); 525 685 686 /* Map generated value types to constant types 687 (user space does not care whether the 688 value is constant or generated) */ 526 689 if (ret.tag == SYSINFO_VAL_FUNCTION_VAL) 527 690 ret.tag = SYSINFO_VAL_VAL; … … 535 698 } 536 699 700 /** Get the sysinfo numerical value (syscall) 701 * 702 * The path string passed from the user space has 703 * to be properly null-terminated (the last passed 704 * character must be null). 705 * 706 * @param path_ptr Sysinfo path in the user address space. 707 * @param path_size Size of the path string. 708 * @param value_ptr User space pointer where to store the 709 * numberical value. 710 * 711 * @return Error code (EOK in case of no error). 712 * 713 */ 537 714 unative_t sys_sysinfo_get_value(void *path_ptr, size_t path_size, 538 715 void *value_ptr) 539 716 { 540 ipl_t ipl = interrupts_disable(); 541 spinlock_lock(&sysinfo_lock); 542 717 /* Avoid other functions to mess with sysinfo 718 while we are reading it */ 719 ipl_t ipl = interrupts_disable(); 720 spinlock_lock(&sysinfo_lock); 721 722 /* Get the item */ 543 723 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 544 724 int rc; 545 725 726 /* Only constant or generated numerical value is returned */ 546 727 if ((ret.tag == SYSINFO_VAL_VAL) || (ret.tag == SYSINFO_VAL_FUNCTION_VAL)) 547 728 rc = copy_to_uspace(value_ptr, &ret.val, sizeof(ret.val)); … … 549 730 rc = EINVAL; 550 731 732 /* N.B.: The generated binary data should be freed */ 551 733 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 552 734 free(ret.data.data); … … 558 740 } 559 741 742 /** Get the sysinfo binary data size (syscall) 743 * 744 * The path string passed from the user space has 745 * to be properly null-terminated (the last passed 746 * character must be null). 747 * 748 * @param path_ptr Sysinfo path in the user address space. 749 * @param path_size Size of the path string. 750 * @param size_ptr User space pointer where to store the 751 * binary data size. 752 * 753 * @return Error code (EOK in case of no error). 754 * 755 */ 560 756 unative_t sys_sysinfo_get_data_size(void *path_ptr, size_t path_size, 561 757 void *size_ptr) 562 758 { 563 ipl_t ipl = interrupts_disable(); 564 spinlock_lock(&sysinfo_lock); 565 759 /* Avoid other functions to mess with sysinfo 760 while we are reading it */ 761 ipl_t ipl = interrupts_disable(); 762 spinlock_lock(&sysinfo_lock); 763 764 /* Get the item */ 566 765 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 567 766 int rc; 568 767 768 /* Only the size of constant or generated binary data is considered */ 569 769 if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) 570 770 rc = copy_to_uspace(size_ptr, &ret.data.size, … … 573 773 rc = EINVAL; 574 774 775 /* N.B.: The generated binary data should be freed */ 575 776 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 576 777 free(ret.data.data); … … 582 783 } 583 784 785 /** Get the sysinfo binary data (syscall) 786 * 787 * The path string passed from the user space has 788 * to be properly null-terminated (the last passed 789 * character must be null). 790 * 791 * The user space buffer must be sized exactly according 792 * to the size of the binary data, otherwise the request 793 * fails. 794 * 795 * @param path_ptr Sysinfo path in the user address space. 796 * @param path_size Size of the path string. 797 * @param buffer_ptr User space pointer to the buffer where 798 * to store the binary data. 799 * @param buffer_size User space buffer size. 800 * 801 * @return Error code (EOK in case of no error). 802 * 803 */ 584 804 unative_t sys_sysinfo_get_data(void *path_ptr, size_t path_size, 585 805 void *buffer_ptr, size_t buffer_size) 586 806 { 587 ipl_t ipl = interrupts_disable(); 588 spinlock_lock(&sysinfo_lock); 589 807 /* Avoid other functions to mess with sysinfo 808 while we are reading it */ 809 ipl_t ipl = interrupts_disable(); 810 spinlock_lock(&sysinfo_lock); 811 812 /* Get the item */ 590 813 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 591 814 int rc; 592 815 816 /* Only constant or generated binary data is considered */ 593 817 if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) { 818 /* Check destination buffer size */ 594 819 if (ret.data.size == buffer_size) 595 820 rc = copy_to_uspace(buffer_ptr, ret.data.data, … … 600 825 rc = EINVAL; 601 826 827 /* N.B.: The generated binary data should be freed */ 602 828 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 603 829 free(ret.data.data); -
uspace/lib/c/generic/stats.c
rfce3536 r80bfb601 43 43 #define SYSINFO_STATS_MAX_PATH 64 44 44 45 /** Get CPUs statistics 46 * 47 * @param count Number of records returned. 48 * 49 * @return Array of stats_cpu_t structures. 50 * If non-NULL then it should be eventually freed 51 * by free(). 52 * 53 */ 45 54 stats_cpu_t *get_stats_cpus(size_t *count) 46 55 { … … 55 64 } 56 65 66 /** Get physical memory statistics 67 * 68 * 69 * @return Pointer to the stats_physmem_t structure. 70 * If non-NULL then it should be eventually freed 71 * by free(). 72 * 73 */ 57 74 stats_physmem_t *get_stats_physmem(void) 58 75 { … … 66 83 } 67 84 85 /** Get task IDs 86 * 87 * @param count Number of IDs returned. 88 * 89 * @return Array of IDs (task_id_t). 90 * If non-NULL then it should be eventually freed 91 * by free(). 92 * 93 */ 68 94 task_id_t *get_stats_tasks(size_t *count) 69 95 { … … 78 104 } 79 105 106 /** Get single task statistics 107 * 108 * @param task_id Task ID we are interested in. 109 * 110 * @return Pointer to the stats_task_t structure. 111 * If non-NULL then it should be eventually freed 112 * by free(). 113 * 114 */ 80 115 stats_task_t *get_stats_task(task_id_t task_id) 81 116 { … … 92 127 } 93 128 129 /** Get system load 130 * 131 * @param count Number of load records returned. 132 * 133 * @return Array of load records (load_t). 134 * If non-NULL then it should be eventually freed 135 * by free(). 136 * 137 */ 94 138 load_t *get_stats_load(size_t *count) 95 139 { … … 104 148 } 105 149 150 /** Get system uptime 151 * 152 * @return System uptime (in seconds). 153 * 154 */ 106 155 sysarg_t get_stats_uptime(void) 107 156 { … … 113 162 } 114 163 164 /** Print load fixed-point value 165 * 166 * Print the load record fixed-point value in decimal 167 * representation on stdout. 168 * 169 * @param upper Load record. 170 * @param dec_length Number of decimal digits to print. 171 * 172 */ 115 173 void print_load_fragment(load_t upper, unsigned int dec_length) 116 174 { -
uspace/lib/c/generic/sysinfo.c
rfce3536 r80bfb601 40 40 #include <bool.h> 41 41 42 /** Get sysinfo item type 43 * 44 * @param path Sysinfo path. 45 * 46 * @return Sysinfo item type. 47 * 48 */ 42 49 sysinfo_item_tag_t sysinfo_get_tag(const char *path) 43 50 { … … 46 53 } 47 54 55 /** Get sysinfo numerical value 56 * 57 * @param path Sysinfo path. 58 * @param value Pointer to store the numerical value to. 59 * 60 * @return EOK if the value was successfully read and 61 * is of SYSINFO_VAL_VAL type. 62 * 63 */ 48 64 int sysinfo_get_value(const char *path, sysarg_t *value) 49 65 { … … 52 68 } 53 69 70 /** Get sysinfo binary data size 71 * 72 * @param path Sysinfo path. 73 * @param value Pointer to store the binary data size. 74 * 75 * @return EOK if the value was successfully read and 76 * is of SYSINFO_VAL_DATA type. 77 * 78 */ 54 79 static int sysinfo_get_data_size(const char *path, size_t *size) 55 80 { … … 58 83 } 59 84 85 /** Get sysinfo binary data 86 * 87 * @param path Sysinfo path. 88 * @param value Pointer to store the binary data size. 89 * 90 * @return Binary data read from sysinfo or NULL if the 91 * sysinfo item value type is not binary data. 92 * The returned non-NULL pointer should be 93 * freed by free(). 94 * 95 */ 60 96 void *sysinfo_get_data(const char *path, size_t *size) 61 97 { 98 /* The binary data size might change during time. 99 Unfortunatelly we cannot allocate the buffer 100 and transfer the data as a single atomic operation. 101 102 Let's hope that the number of iterations is bounded 103 in common cases. */ 104 62 105 while (true) { 106 /* Get the binary data size */ 63 107 int ret = sysinfo_get_data_size(path, size); 64 if (ret != EOK) 108 if (ret != EOK) { 109 /* Not binary data item */ 65 110 return NULL; 111 } 66 112 67 113 void *data = malloc(*size); … … 69 115 return NULL; 70 116 117 /* Get the data */ 71 118 ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path, 72 119 (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size); … … 74 121 return data; 75 122 123 /* Dispose the buffer */ 76 124 free(data); 77 125 78 if (ret != ENOMEM) 126 if (ret != ENOMEM) { 127 /* The failure to get the data was not caused 128 by wrong buffer size */ 79 129 return NULL; 130 } 80 131 } 81 132 } -
uspace/lib/c/include/sysinfo.h
rfce3536 r80bfb601 38 38 #include <libc.h> 39 39 40 /** Sysinfo value types 41 * 42 */ 40 43 typedef enum { 41 44 SYSINFO_VAL_UNDEFINED = 0,
Note:
See TracChangeset
for help on using the changeset viewer.