1 | /* |
---|
2 | * libk/utils.h - useful functions for the kernel |
---|
3 | * |
---|
4 | * Copyright (c) 2015 UPMC Sorbonne Universites |
---|
5 | * |
---|
6 | * This file is part of ALMOS-kernel. |
---|
7 | * |
---|
8 | * ALMOS-kernel is free software; you can redistribute it and/or modify it |
---|
9 | * under the terms of the GNU General Public License as published by |
---|
10 | * the Free Software Foundation; version 2.0 of the License. |
---|
11 | * |
---|
12 | * ALMOS-kernel is distributed in the hope that it will be useful, but |
---|
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | * General Public License for more details. |
---|
16 | * |
---|
17 | * You should have received a copy of the GNU General Public License |
---|
18 | * along with ALMOS-kernel; if not, write to the Free Software Foundation, |
---|
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
---|
20 | */ |
---|
21 | |
---|
22 | #ifndef _UTILS_H_ |
---|
23 | #define _UTILS_H_ |
---|
24 | |
---|
25 | #include <types.h> |
---|
26 | |
---|
27 | struct kernel_iter_s { |
---|
28 | cid_t cid; |
---|
29 | }; |
---|
30 | |
---|
31 | struct kernel_iter_s kernel_list; |
---|
32 | |
---|
33 | /* return the substration of two uint_t while avoid * |
---|
34 | * the overflow case. Big is normally bigger than small.*/ |
---|
35 | #if 0 |
---|
36 | static uint_t uint_subwo(uint_t big, uint_t small) |
---|
37 | { |
---|
38 | if(big >= small) |
---|
39 | return (long)big - (long)small; |
---|
40 | else /* big has overflowed */ |
---|
41 | return (UINT32_MAX - small) + big; |
---|
42 | } |
---|
43 | #else |
---|
44 | #define uint_subwo(big, small) \ |
---|
45 | ({ \ |
---|
46 | uint_t __ret; \ |
---|
47 | if(big >= small) \ |
---|
48 | __ret = big - small; \ |
---|
49 | else /* big has overflowed */ \ |
---|
50 | __ret = (UINT32_MAX - small) + big; \ |
---|
51 | __ret; \ |
---|
52 | }) |
---|
53 | #endif |
---|
54 | |
---|
55 | /* The number of kernel running on the platform (some clusters does not have |
---|
56 | * a kernel, like the I/O cluster. |
---|
57 | */ |
---|
58 | #define KERNEL_TOTAL_NR current_cluster->clstr_wram_nr |
---|
59 | |
---|
60 | /* From Linux */ |
---|
61 | #define container_of(ptr, type, member) ({ \ |
---|
62 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ |
---|
63 | (type *)( (char *)__mptr - offsetof(type,member) );}) |
---|
64 | |
---|
65 | /* Assuming that all running kernels are contiguously in cluster 0,1,2 etc..., |
---|
66 | * and empty cluster and I/O cluster are the two last. This is a very |
---|
67 | * dangerous assumption, but for now we can't do otherwise. It should be |
---|
68 | * marked as FIXME. This comment is also true for kernel_foreach_backward. |
---|
69 | */ |
---|
70 | #define kernel_foreach(iter, next) \ |
---|
71 | iter = &kernel_list; \ |
---|
72 | next = 0; \ |
---|
73 | for ( iter->cid = 0; iter->cid < KERNEL_TOTAL_NR; \ |
---|
74 | iter->cid++, next = iter->cid ) |
---|
75 | |
---|
76 | /* cid_t is an unsigned int16_t and CID_NULL == (cid_t)-1 == 65535. When the |
---|
77 | * loop is doing 0-1, it's equal to 65535, and so equal to CID_NULL, that's |
---|
78 | * why this is the end loop condition. |
---|
79 | * |
---|
80 | * You are not expected to understand this. |
---|
81 | * |
---|
82 | */ |
---|
83 | #define kernel_foreach_backward_init(iter,next) \ |
---|
84 | iter = &kernel_list; \ |
---|
85 | next = KERNEL_TOTAL_NR-1; |
---|
86 | |
---|
87 | #define kernel_foreach_backward(iter, next) \ |
---|
88 | kernel_foreach_backward_init(iter,next) \ |
---|
89 | for ( iter->cid = KERNEL_TOTAL_NR-1; \ |
---|
90 | iter->cid != CID_NULL; \ |
---|
91 | iter->cid--, next = iter->cid ) |
---|
92 | |
---|
93 | #endif /* _UTILS_H_ */ |
---|