[1] | 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_ */ |
---|