/*
* libk/utils.h - useful functions for the kernel
*
* Copyright (c) 2015 UPMC Sorbonne Universites
*
* This file is part of ALMOS-kernel.
*
* ALMOS-kernel is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2.0 of the License.
*
* ALMOS-kernel 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ALMOS-kernel; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include
struct kernel_iter_s {
cid_t cid;
};
struct kernel_iter_s kernel_list;
/* return the substration of two uint_t while avoid *
* the overflow case. Big is normally bigger than small.*/
#if 0
static uint_t uint_subwo(uint_t big, uint_t small)
{
if(big >= small)
return (long)big - (long)small;
else /* big has overflowed */
return (UINT32_MAX - small) + big;
}
#else
#define uint_subwo(big, small) \
({ \
uint_t __ret; \
if(big >= small) \
__ret = big - small; \
else /* big has overflowed */ \
__ret = (UINT32_MAX - small) + big; \
__ret; \
})
#endif
/* The number of kernel running on the platform (some clusters does not have
* a kernel, like the I/O cluster.
*/
#define KERNEL_TOTAL_NR current_cluster->clstr_wram_nr
/* From Linux */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/* Assuming that all running kernels are contiguously in cluster 0,1,2 etc...,
* and empty cluster and I/O cluster are the two last. This is a very
* dangerous assumption, but for now we can't do otherwise. It should be
* marked as FIXME. This comment is also true for kernel_foreach_backward.
*/
#define kernel_foreach(iter, next) \
iter = &kernel_list; \
next = 0; \
for ( iter->cid = 0; iter->cid < KERNEL_TOTAL_NR; \
iter->cid++, next = iter->cid )
/* cid_t is an unsigned int16_t and CID_NULL == (cid_t)-1 == 65535. When the
* loop is doing 0-1, it's equal to 65535, and so equal to CID_NULL, that's
* why this is the end loop condition.
*
* You are not expected to understand this.
*
*/
#define kernel_foreach_backward_init(iter,next) \
iter = &kernel_list; \
next = KERNEL_TOTAL_NR-1;
#define kernel_foreach_backward(iter, next) \
kernel_foreach_backward_init(iter,next) \
for ( iter->cid = KERNEL_TOTAL_NR-1; \
iter->cid != CID_NULL; \
iter->cid--, next = iter->cid )
#endif /* _UTILS_H_ */