futex and rlimit
This commit is contained in:
36
kernel/include/lwk/compiler-gcc.h
Normal file
36
kernel/include/lwk/compiler-gcc.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Never include this file directly. Include <lwk/compiler.h> instead. */
|
||||
|
||||
/*
|
||||
* Common definitions for all gcc versions go here.
|
||||
*/
|
||||
|
||||
|
||||
/* Optimization barrier */
|
||||
/* The "volatile" is due to gcc bugs
|
||||
* NOTE: already defined in aal/manycore/generic/include/aal/cpu.h
|
||||
* #define barrier() __asm__ __volatile__("": : :"memory")
|
||||
*/
|
||||
|
||||
/* This macro obfuscates arithmetic on a variable address so that gcc
|
||||
shouldn't recognize the original var, and make assumptions about it */
|
||||
/*
|
||||
* Versions of the ppc64 compiler before 4.1 had a bug where use of
|
||||
* RELOC_HIDE could trash r30. The bug can be worked around by changing
|
||||
* the inline assembly constraint from =g to =r, in this particular
|
||||
* case either is valid.
|
||||
*/
|
||||
#define RELOC_HIDE(ptr, off) \
|
||||
({ unsigned long __ptr; \
|
||||
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
|
||||
(typeof(ptr)) (__ptr + (off)); })
|
||||
|
||||
|
||||
#define inline inline __attribute__((always_inline))
|
||||
#define __inline__ __inline__ __attribute__((always_inline))
|
||||
#define __inline __inline __attribute__((always_inline))
|
||||
#define __deprecated __attribute__((deprecated))
|
||||
#define noinline __attribute__((noinline))
|
||||
#define __attribute_pure__ __attribute__((pure))
|
||||
#define __attribute_const__ __attribute__((__const__))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
24
kernel/include/lwk/compiler-gcc4.h
Normal file
24
kernel/include/lwk/compiler-gcc4.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Never include this file directly. Include <lwk/compiler.h> instead. */
|
||||
|
||||
/* These definitions are for GCC v4.x. */
|
||||
#include <lwk/compiler-gcc.h>
|
||||
|
||||
#ifdef CONFIG_FORCED_INLINING
|
||||
# undef inline
|
||||
# undef __inline__
|
||||
# undef __inline
|
||||
# define inline inline __attribute__((always_inline))
|
||||
# define __inline__ __inline__ __attribute__((always_inline))
|
||||
# define __inline __inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#define __used __attribute__((__used__))
|
||||
#define __must_check __attribute__((warn_unused_result))
|
||||
#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
|
||||
/*
|
||||
* A trick to suppress uninitialized variable warning without generating any
|
||||
* code
|
||||
*/
|
||||
#define uninitialized_var(x) x = x
|
||||
146
kernel/include/lwk/compiler.h
Normal file
146
kernel/include/lwk/compiler.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef _LWK_COMPILER_H
|
||||
#define _LWK_COMPILER_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef __CHECKER__
|
||||
# define __user __attribute__((noderef, address_space(1)))
|
||||
# define __kernel /* default address space */
|
||||
# define __safe __attribute__((safe))
|
||||
# define __force __attribute__((force))
|
||||
# define __nocast __attribute__((nocast))
|
||||
# define __iomem __attribute__((noderef, address_space(2)))
|
||||
# define __acquires(x) __attribute__((context(0,1)))
|
||||
# define __releases(x) __attribute__((context(1,0)))
|
||||
# define __acquire(x) __context__(1)
|
||||
# define __release(x) __context__(-1)
|
||||
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)
|
||||
# define __unused(x) x __attribute__((unused))
|
||||
extern void __chk_user_ptr(void __user *);
|
||||
extern void __chk_io_ptr(void __iomem *);
|
||||
#else
|
||||
# define __user
|
||||
# define __kernel
|
||||
# define __safe
|
||||
# define __force
|
||||
# define __nocast
|
||||
# define __iomem
|
||||
# define __chk_user_ptr(x) (void)0
|
||||
# define __chk_io_ptr(x) (void)0
|
||||
# define __builtin_warning(x, y...) (1)
|
||||
# define __acquires(x)
|
||||
# define __releases(x)
|
||||
# define __acquire(x) (void)0
|
||||
# define __release(x) (void)0
|
||||
# define __cond_lock(x) (x)
|
||||
# define __unused(x) x
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#if __GNUC__ > 4
|
||||
#error no compiler-gcc.h file for this gcc version
|
||||
#elif __GNUC__ == 4
|
||||
# include <lwk/compiler-gcc4.h>
|
||||
#else
|
||||
# error Sorry, your compiler is too old/not recognized.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generic compiler-dependent macros required for kernel
|
||||
* build go below this comment. Actual compiler/compiler version
|
||||
* specific implementations come from the above header files
|
||||
*/
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
/* Optimization barrier */
|
||||
#ifndef barrier
|
||||
# define barrier() __memory_barrier()
|
||||
#endif
|
||||
|
||||
#ifndef RELOC_HIDE
|
||||
# define RELOC_HIDE(ptr, off) \
|
||||
({ unsigned long __ptr; \
|
||||
__ptr = (unsigned long) (ptr); \
|
||||
(typeof(ptr)) (__ptr + (off)); })
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/*
|
||||
* Allow us to mark functions as 'deprecated' and have gcc emit a nice
|
||||
* warning for each use, in hopes of speeding the functions removal.
|
||||
* Usage is:
|
||||
* int __deprecated foo(void)
|
||||
*/
|
||||
#ifndef __deprecated
|
||||
# define __deprecated /* unimplemented */
|
||||
#endif
|
||||
|
||||
#ifndef __must_check
|
||||
#define __must_check
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allow us to avoid 'defined but not used' warnings on functions and data,
|
||||
* as well as force them to be emitted to the assembly file.
|
||||
*
|
||||
* As of gcc 3.4, static functions that are not marked with attribute((used))
|
||||
* may be elided from the assembly file. As of gcc 3.4, static data not so
|
||||
* marked will not be elided, but this may change in a future gcc version.
|
||||
*
|
||||
* In prior versions of gcc, such functions and data would be emitted, but
|
||||
* would be warned about except with attribute((unused)).
|
||||
*/
|
||||
#ifndef __used
|
||||
# define __used /* unimplemented */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* From the GCC manual:
|
||||
*
|
||||
* Many functions have no effects except the return value and their
|
||||
* return value depends only on the parameters and/or global
|
||||
* variables. Such a function can be subject to common subexpression
|
||||
* elimination and loop optimization just as an arithmetic operator
|
||||
* would be.
|
||||
* [...]
|
||||
*/
|
||||
#ifndef __attribute_pure__
|
||||
# define __attribute_pure__ /* unimplemented */
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
#define noinline
|
||||
#endif
|
||||
|
||||
#ifndef __always_inline
|
||||
#define __always_inline inline
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*
|
||||
* From the GCC manual:
|
||||
*
|
||||
* Many functions do not examine any values except their arguments,
|
||||
* and have no effects except the return value. Basically this is
|
||||
* just slightly more strict class than the `pure' attribute above,
|
||||
* since function is not allowed to read global memory.
|
||||
*
|
||||
* Note that a function that has pointer arguments and examines the
|
||||
* data pointed to must _not_ be declared `const'. Likewise, a
|
||||
* function that calls a non-`const' function usually must not be
|
||||
* `const'. It does not make sense for a `const' function to return
|
||||
* `void'.
|
||||
*/
|
||||
#ifndef __attribute_const__
|
||||
# define __attribute_const__ /* unimplemented */
|
||||
#endif
|
||||
|
||||
#endif /* _LWK_COMPILER_H */
|
||||
109
kernel/include/lwk/futex.h
Normal file
109
kernel/include/lwk/futex.h
Normal file
@@ -0,0 +1,109 @@
|
||||
#ifndef _LWK_FUTEX_H
|
||||
#define _LWK_FUTEX_H
|
||||
|
||||
/** \name Futex Commands
|
||||
* @{
|
||||
*/
|
||||
#define FUTEX_WAIT 0
|
||||
#define FUTEX_WAKE 1
|
||||
#define FUTEX_CMP_REQUEUE 4
|
||||
#define FUTEX_WAKE_OP 5
|
||||
#define FUTEX_WAIT_BITSET 9
|
||||
#define FUTEX_WAKE_BITSET 10
|
||||
// @}
|
||||
|
||||
#define FUTEX_PRIVATE_FLAG 128
|
||||
#define FUTEX_CLOCK_REALTIME 256
|
||||
#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
|
||||
|
||||
/** \name Futex Operations, used for FUTEX_WAKE_OP
|
||||
* @{
|
||||
*/
|
||||
#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
|
||||
#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
|
||||
#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */
|
||||
#define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */
|
||||
#define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */
|
||||
|
||||
#define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */
|
||||
|
||||
#define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */
|
||||
#define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */
|
||||
#define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */
|
||||
#define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */
|
||||
#define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */
|
||||
#define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */
|
||||
// @}
|
||||
|
||||
/* FUTEX_WAKE_OP will perform atomically
|
||||
int oldval = *(int *)UADDR2;
|
||||
*(int *)UADDR2 = oldval OP OPARG;
|
||||
if (oldval CMP CMPARG)
|
||||
wake UADDR2; */
|
||||
#define FUTEX_OP(op, oparg, cmp, cmparg) \
|
||||
(((op & 0xf) << 28) | ((cmp & 0xf) << 24) \
|
||||
| ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
|
||||
|
||||
/*
|
||||
* bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
|
||||
* match of any bit.
|
||||
*/
|
||||
#define FUTEX_BITSET_MATCH_ANY 0xffffffff
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <lwk/spinlock.h>
|
||||
#include <lwk/list.h>
|
||||
#include <lwk/waitq.h>
|
||||
#include <arch/futex.h>
|
||||
|
||||
#define FUTEX_HASHBITS 8 /* 256 entries in each futex hash tbl */
|
||||
|
||||
/** Futex tracking structure.
|
||||
*
|
||||
* A futex has a woken state, just like tasks have TASK_RUNNING.
|
||||
* It is considered woken when list_empty(&futex->link) || futex->lock_ptr == 0.
|
||||
* The order of wakup is always to make the first condition true, then
|
||||
* wake up futex->waitq, then make the second condition true.
|
||||
*/
|
||||
struct futex {
|
||||
struct list_head link;
|
||||
struct waitq waitq;
|
||||
spinlock_t * lock_ptr;
|
||||
uint32_t __user * uaddr;
|
||||
uint32_t bitset;
|
||||
};
|
||||
|
||||
struct futex_queue {
|
||||
spinlock_t lock;
|
||||
struct list_head futex_list;
|
||||
};
|
||||
|
||||
extern void
|
||||
futex_queue_init(
|
||||
struct futex_queue * queue
|
||||
);
|
||||
|
||||
extern int
|
||||
futex(
|
||||
uint32_t __user * uaddr,
|
||||
int op,
|
||||
uint32_t val,
|
||||
uint64_t timeout,
|
||||
uint32_t __user * uaddr2,
|
||||
uint32_t val2,
|
||||
uint32_t val3
|
||||
);
|
||||
|
||||
extern long
|
||||
sys_futex(
|
||||
uint32_t __user * uaddr,
|
||||
int op,
|
||||
uint32_t val,
|
||||
struct timespec __user * utime,
|
||||
uint32_t __user * uaddr2,
|
||||
uint32_t val3
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
25
kernel/include/lwk/stddef.h
Normal file
25
kernel/include/lwk/stddef.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _LWK_STDDEF_H
|
||||
#define _LWK_STDDEF_H
|
||||
|
||||
#include <lwk/compiler.h>
|
||||
|
||||
#undef NULL
|
||||
#if defined(__cplusplus)
|
||||
#define NULL 0
|
||||
#else
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#undef offsetof
|
||||
#ifdef __compiler_offsetof
|
||||
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
|
||||
#else
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user