parent
0a1664b892
commit
146b34bf40
|
@ -3,8 +3,7 @@ SHARED_LIB = yes
|
||||||
LIB_DIR = $(REP_DIR)/src/lib/lxip
|
LIB_DIR = $(REP_DIR)/src/lib/lxip
|
||||||
LIB_INC_DIR = $(LIB_DIR)/include
|
LIB_INC_DIR = $(LIB_DIR)/include
|
||||||
|
|
||||||
# FIXME should we *really* effecticely add dde_kit to this shared library?
|
LIBS += lx
|
||||||
LIBS += dde_kit
|
|
||||||
|
|
||||||
LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip
|
LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip
|
||||||
NET_DIR := $(LX_CONTRIB_DIR)/net
|
NET_DIR := $(LX_CONTRIB_DIR)/net
|
||||||
|
|
|
@ -323,7 +323,6 @@ DUMMY(-1, mod_delayed_work)
|
||||||
DUMMY(-1, module_put)
|
DUMMY(-1, module_put)
|
||||||
DUMMY(-1, move_addr_to_kernel)
|
DUMMY(-1, move_addr_to_kernel)
|
||||||
DUMMY(-1, mq_qdisc_ops)
|
DUMMY(-1, mq_qdisc_ops)
|
||||||
DUMMY(-1, msecs_to_jiffies)
|
|
||||||
DUMMY(-1, msleep)
|
DUMMY(-1, msleep)
|
||||||
DUMMY(-1, mutex_is_locked)
|
DUMMY(-1, mutex_is_locked)
|
||||||
DUMMY(-1, need_resched)
|
DUMMY(-1, need_resched)
|
||||||
|
|
|
@ -17,14 +17,7 @@
|
||||||
#ifndef _LX_EMUL_H_
|
#ifndef _LX_EMUL_H_
|
||||||
#define _LX_EMUL_H_
|
#define _LX_EMUL_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include <lx/lx.h>
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#include <dde_kit/panic.h>
|
|
||||||
#include <dde_kit/printf.h>
|
|
||||||
#include <dde_kit/types.h>
|
|
||||||
|
|
||||||
#define DEBUG_PRINTK 1
|
#define DEBUG_PRINTK 1
|
||||||
#define DEBUG_SLAB 0
|
#define DEBUG_SLAB 0
|
||||||
|
@ -39,31 +32,6 @@ extern "C" {
|
||||||
#define KBUILD_MODNAME "mod-noname"
|
#define KBUILD_MODNAME "mod-noname"
|
||||||
|
|
||||||
|
|
||||||
/***************
|
|
||||||
** asm/bug.h **
|
|
||||||
***************/
|
|
||||||
|
|
||||||
#define WARN_ON(condition) ({ \
|
|
||||||
int ret = !!(condition); \
|
|
||||||
if (ret) dde_kit_printf("[%s] WARN_ON(" #condition ")\n", __func__); \
|
|
||||||
ret; })
|
|
||||||
|
|
||||||
#define WARN(condition, format, ...) ({ \
|
|
||||||
int ret = !!(condition); \
|
|
||||||
if (ret) dde_kit_printf("[%s] WARN(" #condition ") " format "\n" , __func__, __VA_ARGS__); \
|
|
||||||
ret; })
|
|
||||||
|
|
||||||
#define WARN_ON_ONCE WARN_ON
|
|
||||||
#define WARN_ONCE WARN
|
|
||||||
|
|
||||||
#define BUG() do { \
|
|
||||||
dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
|
|
||||||
while (1); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define BUG_ON(condition) do { if (condition) BUG(); } while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
** linux/errno.h and friends **
|
** linux/errno.h and friends **
|
||||||
*******************************/
|
*******************************/
|
||||||
|
@ -239,31 +207,10 @@ int try_module_get(struct module *);
|
||||||
#define CONFIG_DEFAULT_TCP_CONG "cubic"
|
#define CONFIG_DEFAULT_TCP_CONG "cubic"
|
||||||
|
|
||||||
|
|
||||||
/***************
|
|
||||||
** asm/bug.h **
|
|
||||||
***************/
|
|
||||||
|
|
||||||
#define BUG() do { \
|
|
||||||
dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
|
|
||||||
while (1); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
** linux/types.h **
|
** linux/types.h **
|
||||||
*******************/
|
*******************/
|
||||||
|
|
||||||
typedef dde_kit_int8_t int8_t;
|
|
||||||
typedef dde_kit_int16_t int16_t;
|
|
||||||
typedef dde_kit_int32_t int32_t;
|
|
||||||
typedef dde_kit_int64_t int64_t;
|
|
||||||
|
|
||||||
typedef dde_kit_uint8_t uint8_t;
|
|
||||||
typedef dde_kit_uint16_t uint16_t;
|
|
||||||
typedef dde_kit_uint32_t uint32_t;
|
|
||||||
typedef dde_kit_uint64_t uint64_t;
|
|
||||||
typedef dde_kit_size_t size_t;
|
|
||||||
|
|
||||||
typedef uint32_t uint;
|
typedef uint32_t uint;
|
||||||
|
|
||||||
typedef int8_t s8;
|
typedef int8_t s8;
|
||||||
|
@ -353,10 +300,7 @@ enum { true = 1, false = 0 };
|
||||||
** linux/jiffies.h **
|
** linux/jiffies.h **
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
/* we directly map 'jiffies' to 'dde_kit_timer_ticks' */
|
extern unsigned long jiffies;
|
||||||
#define jiffies dde_kit_timer_ticks
|
|
||||||
|
|
||||||
extern volatile unsigned long jiffies;
|
|
||||||
|
|
||||||
enum { INITIAL_JIFFIES = 0 };
|
enum { INITIAL_JIFFIES = 0 };
|
||||||
|
|
||||||
|
@ -371,6 +315,7 @@ static inline long time_before(long a, long b) { return time_after(b, a); }
|
||||||
static inline long time_before_eq(long a, long b) { return time_after_eq(b ,a); }
|
static inline long time_before_eq(long a, long b) { return time_after_eq(b ,a); }
|
||||||
|
|
||||||
clock_t jiffies_to_clock_t(unsigned long);
|
clock_t jiffies_to_clock_t(unsigned long);
|
||||||
|
void update_jiffies(void);
|
||||||
|
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
|
@ -441,11 +386,11 @@ void sg_set_page(struct scatterlist *, struct page *, unsigned int,
|
||||||
|
|
||||||
#define KERN_WARNING KERN_WARN
|
#define KERN_WARNING KERN_WARN
|
||||||
|
|
||||||
#define pr_crit(fmt, ...) dde_kit_printf(KERN_CRIT fmt, ##__VA_ARGS__)
|
#define pr_crit(fmt, ...) lx_printf(KERN_CRIT fmt, ##__VA_ARGS__)
|
||||||
#define pr_emerg(fmt, ...) dde_kit_printf(KERN_EMERG fmt, ##__VA_ARGS__)
|
#define pr_emerg(fmt, ...) lx_printf(KERN_EMERG fmt, ##__VA_ARGS__)
|
||||||
#define pr_err(fmt, ...) dde_kit_printf(KERN_ERR fmt, ##__VA_ARGS__)
|
#define pr_err(fmt, ...) lx_printf(KERN_ERR fmt, ##__VA_ARGS__)
|
||||||
#define pr_warn(fmt, ...) dde_kit_printf(KERN_WARN fmt, ##__VA_ARGS__)
|
#define pr_warn(fmt, ...) lx_printf(KERN_WARN fmt, ##__VA_ARGS__)
|
||||||
#define pr_info(fmt, ...) dde_kit_printf(KERN_INFO fmt, ##__VA_ARGS__)
|
#define pr_info(fmt, ...) lx_printf(KERN_INFO fmt, ##__VA_ARGS__)
|
||||||
#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__)
|
#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__)
|
||||||
#define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__)
|
#define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
@ -468,15 +413,14 @@ static inline int _printk(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
dde_kit_vprintf(fmt, args);
|
lx_vprintf(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_PRINTK
|
#if DEBUG_PRINTK
|
||||||
#define printk _printk
|
#define printk _printk
|
||||||
#define vprintk dde_kit_vprintf
|
#define vprintk lx_vprintf
|
||||||
#define panic dde_kit_panic
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int printk(const char *fmt, ...)
|
static inline int printk(const char *fmt, ...)
|
||||||
|
@ -485,7 +429,6 @@ static inline int printk(const char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define vprintk(...)
|
#define vprintk(...)
|
||||||
#define panic(...)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -974,9 +917,6 @@ enum {
|
||||||
PAGE_SHIFT = 12,
|
PAGE_SHIFT = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define private priv
|
|
||||||
#endif
|
|
||||||
struct page
|
struct page
|
||||||
{
|
{
|
||||||
int pfmemalloc;
|
int pfmemalloc;
|
||||||
|
@ -984,9 +924,6 @@ struct page
|
||||||
atomic_t _count;
|
atomic_t _count;
|
||||||
void *addr;
|
void *addr;
|
||||||
unsigned long private;
|
unsigned long private;
|
||||||
#ifdef __cplusplus
|
|
||||||
#undef priv
|
|
||||||
#endif
|
|
||||||
} __attribute((packed));
|
} __attribute((packed));
|
||||||
|
|
||||||
|
|
||||||
|
@ -2241,17 +2178,12 @@ ssize_t splice_to_pipe(struct pipe_inode_info *, struct splice_pipe_desc *);
|
||||||
/*****************
|
/*****************
|
||||||
** linux/aio.h **
|
** linux/aio.h **
|
||||||
*****************/
|
*****************/
|
||||||
#ifdef __cplusplus
|
|
||||||
#define private priv
|
|
||||||
#endif
|
|
||||||
struct kiocb
|
struct kiocb
|
||||||
{
|
{
|
||||||
void *private;
|
void *private;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#undef private
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
** linux/uio.h **
|
** linux/uio.h **
|
||||||
|
@ -2499,9 +2431,7 @@ struct u64_stats_sync { };
|
||||||
** net/net_namespace.h **
|
** net/net_namespace.h **
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
#define new _new
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#undef new
|
|
||||||
#include <uapi/linux/snmp.h>
|
#include <uapi/linux/snmp.h>
|
||||||
#include <net/netns/mib.h>
|
#include <net/netns/mib.h>
|
||||||
#include <net/netns/ipv4.h>
|
#include <net/netns/ipv4.h>
|
||||||
|
@ -2795,13 +2725,7 @@ void csum_replace2(__sum16 *, __be16, __be16);
|
||||||
** uapi/linux/net_tstamp.h **
|
** uapi/linux/net_tstamp.h **
|
||||||
*****************************/
|
*****************************/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define class device_class
|
|
||||||
#endif
|
|
||||||
#include <uapi/linux/if_link.h>
|
#include <uapi/linux/if_link.h>
|
||||||
#ifdef __cplusplus
|
|
||||||
#undef class
|
|
||||||
#endif
|
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -3327,9 +3251,5 @@ void log_sock(struct socket *sock);
|
||||||
|
|
||||||
void lx_trace_event(char const *, ...) __attribute__((format(printf, 1, 2)));
|
void lx_trace_event(char const *, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* _LX_EMUL_H_ */
|
#endif /* _LX_EMUL_H_ */
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
#include <dde_kit/timer.h>
|
|
||||||
#include <linux/inetdevice.h>
|
#include <linux/inetdevice.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
@ -58,9 +57,6 @@ int lxip_init(char *address_config)
|
||||||
/* init data */
|
/* init data */
|
||||||
INIT_LIST_HEAD(&init_net.dev_base_head);
|
INIT_LIST_HEAD(&init_net.dev_base_head);
|
||||||
|
|
||||||
/*start jiffies */
|
|
||||||
dde_kit_timer_init(0, 0);
|
|
||||||
|
|
||||||
/* call __setup stuff */
|
/* call __setup stuff */
|
||||||
__ip_auto_config_setup(address_config);
|
__ip_auto_config_setup(address_config);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <net/ip_fib.h>
|
#include <net/ip_fib.h>
|
||||||
#include <uapi/linux/rtnetlink.h>
|
#include <uapi/linux/rtnetlink.h>
|
||||||
#include <dde_kit/memory.h>
|
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
|
@ -33,7 +32,7 @@ struct kmem_cache
|
||||||
struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,
|
struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,
|
||||||
unsigned long falgs, void (*ctor)(void *))
|
unsigned long falgs, void (*ctor)(void *))
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size);
|
lx_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size);
|
||||||
|
|
||||||
struct kmem_cache *cache;
|
struct kmem_cache *cache;
|
||||||
|
|
||||||
|
@ -57,49 +56,25 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align
|
||||||
|
|
||||||
void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node)
|
void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node)
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
|
lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
|
||||||
return kmalloc(cache->size, 0);
|
return kmalloc(cache->size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
|
void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
|
lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
|
||||||
return kmalloc(cache->size, 0);
|
return kmalloc(cache->size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void kmem_cache_free(struct kmem_cache *cache, void *objp)
|
void kmem_cache_free(struct kmem_cache *cache, void *objp)
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp);
|
lx_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp);
|
||||||
kfree(objp);
|
kfree(objp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *alloc_large_system_hash(const char *tablename,
|
|
||||||
unsigned long bucketsize,
|
|
||||||
unsigned long numentries,
|
|
||||||
int scale,
|
|
||||||
int flags,
|
|
||||||
unsigned int *_hash_shift,
|
|
||||||
unsigned int *_hash_mask,
|
|
||||||
unsigned long low_limit,
|
|
||||||
unsigned long high_limit)
|
|
||||||
{
|
|
||||||
unsigned long elements = numentries ? numentries : high_limit;
|
|
||||||
unsigned long nlog2 = ilog2(elements);
|
|
||||||
nlog2 <<= (1 << nlog2) < elements ? 1 : 0;
|
|
||||||
|
|
||||||
void *table = dde_kit_simple_malloc(elements * bucketsize);
|
|
||||||
|
|
||||||
if (_hash_mask)
|
|
||||||
*_hash_mask = (1 << nlog2) - 1;
|
|
||||||
if (_hash_shift)
|
|
||||||
*_hash_shift = nlog2;
|
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
** linux/bitmap.h **
|
** linux/bitmap.h **
|
||||||
********************/
|
********************/
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <trace/timestamp.h>
|
#include <trace/timestamp.h>
|
||||||
|
|
||||||
|
#include <lx/extern_c_begin.h>
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
|
#include <lx/extern_c_end.h>
|
||||||
|
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <dde_kit/memory.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VM-area to reserve for back-end allocator
|
* VM-area to reserve for back-end allocator
|
||||||
|
@ -379,6 +379,7 @@ void *kzalloc_node(size_t size, gfp_t flags, int node)
|
||||||
return kzalloc(size, 0);
|
return kzalloc(size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ksize(const void *p)
|
size_t ksize(const void *p)
|
||||||
{
|
{
|
||||||
if (!(Malloc::mem()->inside((Genode::addr_t)p))) {
|
if (!(Malloc::mem()->inside((Genode::addr_t)p))) {
|
||||||
|
@ -391,6 +392,32 @@ size_t ksize(const void *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *alloc_large_system_hash(const char *tablename,
|
||||||
|
unsigned long bucketsize,
|
||||||
|
unsigned long numentries,
|
||||||
|
int scale,
|
||||||
|
int flags,
|
||||||
|
unsigned int *_hash_shift,
|
||||||
|
unsigned int *_hash_mask,
|
||||||
|
unsigned long low_limit,
|
||||||
|
unsigned long high_limit)
|
||||||
|
{
|
||||||
|
unsigned long elements = numentries ? numentries : high_limit;
|
||||||
|
unsigned long nlog2 = ilog2(elements);
|
||||||
|
nlog2 <<= (1 << nlog2) < elements ? 1 : 0;
|
||||||
|
|
||||||
|
void *table = Genode::env()->heap()->alloc(elements * bucketsize);
|
||||||
|
|
||||||
|
if (_hash_mask)
|
||||||
|
*_hash_mask = (1 << nlog2) - 1;
|
||||||
|
if (_hash_shift)
|
||||||
|
*_hash_shift = nlog2;
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
** linux/string.h **
|
** linux/string.h **
|
||||||
********************/
|
********************/
|
||||||
|
@ -515,7 +542,8 @@ static void __wait_event(signed long timeout)
|
||||||
while (timeout > jiffies && !Net::Env::receiver()->pending())
|
while (timeout > jiffies && !Net::Env::receiver()->pending())
|
||||||
{
|
{
|
||||||
timer.msleep(1);
|
timer.msleep(1);
|
||||||
//dde_kit_thread_msleep(1);
|
update_jiffies();
|
||||||
|
|
||||||
if (timeout <= jiffies)
|
if (timeout <= jiffies)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -584,7 +612,7 @@ class Avl_page : public Genode::Avl_node<Avl_page>
|
||||||
_page->addr = (void *)_addr;
|
_page->addr = (void *)_addr;
|
||||||
atomic_set(&_page->_count, 1);
|
atomic_set(&_page->_count, 1);
|
||||||
|
|
||||||
dde_kit_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size);
|
lx_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Avl_page()
|
virtual ~Avl_page()
|
||||||
|
@ -632,7 +660,7 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
|
||||||
struct page *virt_to_head_page(const void *x)
|
struct page *virt_to_head_page(const void *x)
|
||||||
{
|
{
|
||||||
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)x);
|
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)x);
|
||||||
dde_kit_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0);
|
lx_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0);
|
||||||
|
|
||||||
return p ? p->page() : 0;
|
return p ? p->page() : 0;
|
||||||
}
|
}
|
||||||
|
@ -643,7 +671,7 @@ void put_page(struct page *page)
|
||||||
if (!atomic_dec_and_test(&page->_count))
|
if (!atomic_dec_and_test(&page->_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dde_kit_log(DEBUG_SLAB, "put_page: %p", page);
|
lx_log(DEBUG_SLAB, "put_page: %p", page);
|
||||||
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)page->addr);
|
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)page->addr);
|
||||||
|
|
||||||
tree.remove(p);
|
tree.remove(p);
|
||||||
|
|
|
@ -26,18 +26,17 @@ static const bool verbose = false;
|
||||||
|
|
||||||
|
|
||||||
namespace Linux {
|
namespace Linux {
|
||||||
extern "C" {
|
#include <lx/extern_c_begin.h>
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <uapi/linux/in.h>
|
#include <uapi/linux/in.h>
|
||||||
|
|
||||||
extern int sock_setsockopt(struct socket *sock, int level,
|
extern int sock_setsockopt(struct socket *sock, int level,
|
||||||
int op, char __user *optval,
|
int op, char __user *optval,
|
||||||
unsigned int optlen);
|
unsigned int optlen);
|
||||||
extern int sock_getsockopt(struct socket *sock, int level,
|
extern int sock_getsockopt(struct socket *sock, int level,
|
||||||
int op, char __user *optval,
|
int op, char __user *optval,
|
||||||
int __user *optlen);
|
int __user *optlen);
|
||||||
}
|
#include <lx/extern_c_end.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
|
|
|
@ -13,85 +13,289 @@
|
||||||
|
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
|
#include <base/tslab.h>
|
||||||
|
#include <os/server.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
#include <util/volatile_object.h>
|
||||||
|
|
||||||
|
#include <lx/extern_c_begin.h>
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
|
#include <lx/extern_c_end.h>
|
||||||
|
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
|
|
||||||
extern "C" {
|
#include <lx/list.h>
|
||||||
#include <dde_kit/timer.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handler(void *timer);
|
|
||||||
|
/*********************
|
||||||
|
** linux/jiffies.h **
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
unsigned long jiffies;
|
||||||
|
|
||||||
|
unsigned long msecs_to_jiffies(const unsigned int m) { return m / (1000 / HZ); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal context for time-outs
|
* Lx::Timer
|
||||||
*/
|
*/
|
||||||
class Timer_context
|
namespace Lx {
|
||||||
|
class Timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Lx::Timer
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context encapsulates a regular linux timer_list
|
||||||
|
*/
|
||||||
|
struct Context : public Lx::List<Context>::Element
|
||||||
|
{
|
||||||
|
enum { INVALID_TIMEOUT = ~0UL };
|
||||||
|
enum Type { LIST };
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
void *timer;
|
||||||
|
bool pending { false };
|
||||||
|
unsigned long timeout { INVALID_TIMEOUT }; /* absolute in jiffies */
|
||||||
|
bool programmed { false };
|
||||||
|
|
||||||
|
Context(struct timer_list *timer) : type(LIST), timer(timer) { }
|
||||||
|
|
||||||
|
void expires(unsigned long e)
|
||||||
|
{
|
||||||
|
if (type == LIST)
|
||||||
|
static_cast<timer_list *>(timer)->expires = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void function()
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case LIST:
|
||||||
|
{
|
||||||
|
timer_list *t = static_cast<timer_list *>(timer);
|
||||||
|
if (t->function)
|
||||||
|
t->function(t->data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
timer_list *_timer; /* Linux timer */
|
::Timer::Connection _timer_conn;
|
||||||
dde_kit_timer *_dde_timer; /* DDE kit timer */
|
Lx::List<Context> _list;
|
||||||
Genode::Signal_dispatcher<Timer_context> _dispatcher;
|
Genode::Signal_dispatcher<Lx::Timer> _dispatcher;
|
||||||
|
Genode::Tslab<Context, 32 * sizeof(Context)> _timer_alloc;
|
||||||
/* call timer function */
|
|
||||||
void _handle(unsigned) { _timer->function(_timer->data); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Timer_context(timer_list *timer)
|
bool ready { true };
|
||||||
: _timer(timer), _dde_timer(0),
|
|
||||||
_dispatcher(*Net::Env::receiver(), *this, &Timer_context::_handle) {}
|
|
||||||
|
|
||||||
/* schedule next timeout */
|
private:
|
||||||
void schedule(unsigned long expires)
|
|
||||||
|
/**
|
||||||
|
* Lookup local timer
|
||||||
|
*/
|
||||||
|
Context *_find_context(void const *timer)
|
||||||
{
|
{
|
||||||
if (!_dde_timer)
|
for (Context *c = _list.first(); c; c = c->next())
|
||||||
_dde_timer = dde_kit_timer_add(handler, this, expires);
|
if (c->timer == timer)
|
||||||
else
|
return c;
|
||||||
dde_kit_timer_schedule_absolute(_dde_timer, expires);
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if timer is pending
|
* Program the first timer in the list
|
||||||
|
*
|
||||||
|
* The first timer is programmed if the 'programmed' flag was not set
|
||||||
|
* before. The second timer is flagged as not programmed as
|
||||||
|
* 'Timer::trigger_once' invalidates former registered one-shot
|
||||||
|
* timeouts.
|
||||||
*/
|
*/
|
||||||
bool pending() const
|
void _program_first_timer()
|
||||||
{
|
{
|
||||||
return _dde_timer ? dde_kit_timer_pending(_dde_timer) : false;
|
Context *ctx = _list.first();
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctx->programmed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* calculate relative microseconds for trigger */
|
||||||
|
unsigned long us = ctx->timeout > jiffies ?
|
||||||
|
jiffies_to_msecs(ctx->timeout - jiffies) * 1000 : 0;
|
||||||
|
_timer_conn.trigger_once(us);
|
||||||
|
|
||||||
|
ctx->programmed = true;
|
||||||
|
|
||||||
|
/* possibly programmed successor must be reprogrammed later */
|
||||||
|
if (Context *next = ctx->next())
|
||||||
|
next->programmed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return internal signal cap
|
* Schedule timer
|
||||||
|
*
|
||||||
|
* Add the context to the scheduling list depending on its timeout
|
||||||
|
* and reprogram the first timer.
|
||||||
*/
|
*/
|
||||||
Genode::Signal_context_capability cap() const { return _dispatcher; }
|
void _schedule_timer(Context *ctx, unsigned long expires)
|
||||||
void submit() { _dispatcher.submit(1); }
|
{
|
||||||
|
_list.remove(ctx);
|
||||||
|
|
||||||
|
ctx->timeout = expires;
|
||||||
|
ctx->pending = true;
|
||||||
|
ctx->programmed = false;
|
||||||
|
/*
|
||||||
|
* Also write the timeout value to the expires field in
|
||||||
|
* struct timer_list because the checks
|
||||||
|
* it directly.
|
||||||
|
*/
|
||||||
|
ctx->expires(expires);
|
||||||
|
|
||||||
|
Context *c;
|
||||||
|
for (c = _list.first(); c; c = c->next())
|
||||||
|
if (ctx->timeout <= c->timeout)
|
||||||
|
break;
|
||||||
|
_list.insert_before(ctx, c);
|
||||||
|
|
||||||
|
_program_first_timer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert 'timer_list' to 'Timer_conext'
|
* Handle trigger_once signal
|
||||||
*/
|
*/
|
||||||
static Timer_context *to_ctx(timer_list const *timer) {
|
void _handle(unsigned)
|
||||||
return static_cast<Timer_context *>(timer->timer); }
|
|
||||||
|
|
||||||
void remove()
|
|
||||||
{
|
{
|
||||||
if (_dde_timer)
|
update_jiffies();
|
||||||
dde_kit_timer_del(_dde_timer);
|
|
||||||
|
|
||||||
_dde_timer = 0;
|
while (Lx::Timer::Context *ctx = _list.first()) {
|
||||||
|
if (ctx->timeout > jiffies)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ctx->function();
|
||||||
|
del(ctx->timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Timer()
|
||||||
|
:
|
||||||
|
_dispatcher(*Net::Env::receiver(), *this, &Lx::Timer::_handle),
|
||||||
|
_timer_alloc(Genode::env()->heap())
|
||||||
|
{
|
||||||
|
_timer_conn.sigh(_dispatcher);
|
||||||
|
jiffies = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new linux timer
|
||||||
|
*/
|
||||||
|
template <typename TIMER>
|
||||||
|
void add(TIMER *timer)
|
||||||
|
{
|
||||||
|
Context *t = new (&_timer_alloc) Context(timer);
|
||||||
|
_list.append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete linux timer
|
||||||
|
*/
|
||||||
|
int del(void *timer)
|
||||||
|
{
|
||||||
|
Context *ctx = _find_context(timer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the timer expired it was already cleaned up after its
|
||||||
|
* execution.
|
||||||
|
*/
|
||||||
|
if (!ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
|
||||||
|
|
||||||
|
_list.remove(ctx);
|
||||||
|
destroy(&_timer_alloc, ctx);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial scheduling of linux timer
|
||||||
|
*/
|
||||||
|
int schedule(void *timer, unsigned long expires)
|
||||||
|
{
|
||||||
|
Context *ctx = _find_context(timer);
|
||||||
|
if (!ctx) {
|
||||||
|
PERR("schedule unknown timer %p", timer);
|
||||||
|
return -1; /* XXX better use 0 as rv? */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If timer was already active return 1, otherwise 0. The return
|
||||||
|
* value is needed by mod_timer().
|
||||||
|
*/
|
||||||
|
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
|
||||||
|
|
||||||
|
_schedule_timer(ctx, expires);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule next linux timer
|
||||||
|
*/
|
||||||
|
void schedule_next() { _program_first_timer(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the timer is currently pending
|
||||||
|
*/
|
||||||
|
bool pending(void const *timer)
|
||||||
|
{
|
||||||
|
Context *ctx = _find_context(timer);
|
||||||
|
if (!ctx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *find(struct timer_list const *timer) {
|
||||||
|
return _find_context(timer); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update jiffie counter
|
||||||
|
*/
|
||||||
|
void update_jiffies()
|
||||||
|
{
|
||||||
|
jiffies = msecs_to_jiffies(_timer_conn.elapsed_ms());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get first timer context
|
||||||
|
*/
|
||||||
|
Context* first() { return _list.first(); }
|
||||||
|
|
||||||
|
static Timer &t()
|
||||||
|
{
|
||||||
|
static Lx::Timer _t;
|
||||||
|
return _t;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
void update_jiffies()
|
||||||
* C handler for DDE timer interface
|
|
||||||
*/
|
|
||||||
static void handler(void *timer)
|
|
||||||
{
|
{
|
||||||
Timer_context *t = static_cast<Timer_context *>(timer);
|
Lx::Timer::t().update_jiffies();
|
||||||
t->submit();
|
|
||||||
/* set context and submit
|
|
||||||
Genode::Signal_transmitter transmitter(t->cap());
|
|
||||||
transmitter.submit(); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,9 +303,7 @@ static void handler(void *timer)
|
||||||
** linux/timer.h **
|
** linux/timer.h **
|
||||||
*******************/
|
*******************/
|
||||||
|
|
||||||
void init_timer(struct timer_list *timer) {
|
void init_timer(struct timer_list *timer) { }
|
||||||
timer->timer = (void *) new (Genode::env()->heap()) Timer_context(timer); }
|
|
||||||
|
|
||||||
|
|
||||||
void add_timer(struct timer_list *timer)
|
void add_timer(struct timer_list *timer)
|
||||||
{
|
{
|
||||||
|
@ -110,12 +312,15 @@ void add_timer(struct timer_list *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int mod_timer(struct timer_list *timer, unsigned long expires)
|
int mod_timer(struct timer_list *timer, unsigned long expires)
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_TIMER, "Timer: %p j: %lu ex: %lu func %p",
|
update_jiffies();
|
||||||
timer, jiffies, expires, timer->function);
|
|
||||||
Timer_context::to_ctx(timer)->schedule(expires);
|
if (!Lx::Timer::t().find(timer))
|
||||||
return 0;
|
Lx::Timer::t().add(timer);
|
||||||
|
|
||||||
|
return Lx::Timer::t().schedule(timer, expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,22 +329,25 @@ void setup_timer(struct timer_list *timer,void (*function)(unsigned long),
|
||||||
{
|
{
|
||||||
timer->function = function;
|
timer->function = function;
|
||||||
timer->data = data;
|
timer->data = data;
|
||||||
init_timer(timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int timer_pending(const struct timer_list * timer)
|
int timer_pending(const struct timer_list * timer)
|
||||||
{
|
{
|
||||||
bool pending = Timer_context::to_ctx(timer)->pending();
|
bool pending = Lx::Timer::t().pending(timer);
|
||||||
dde_kit_log(DEBUG_TIMER, "Pending %p %u", timer, pending);
|
lx_log(DEBUG_TIMER, "Pending %p %u", timer, pending);
|
||||||
return pending;
|
return pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int del_timer(struct timer_list *timer)
|
int del_timer(struct timer_list *timer)
|
||||||
{
|
{
|
||||||
dde_kit_log(DEBUG_TIMER, "Delete timer %p", timer);
|
update_jiffies();
|
||||||
Timer_context::to_ctx(timer)->remove();
|
lx_log(DEBUG_TIMER, "Delete timer %p", timer);
|
||||||
return 0;
|
int rv = Lx::Timer::t().del(timer);
|
||||||
|
Lx::Timer::t().schedule_next();
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,6 @@ typedef unsigned short ushort;
|
||||||
** linux/jiffies.h **
|
** linux/jiffies.h **
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
/* we directly map 'jiffies' to 'dde_kit_timer_ticks' */
|
|
||||||
extern unsigned long jiffies;
|
extern unsigned long jiffies;
|
||||||
unsigned long msecs_to_jiffies(const unsigned int m);
|
unsigned long msecs_to_jiffies(const unsigned int m);
|
||||||
unsigned int jiffies_to_msecs(const unsigned long j);
|
unsigned int jiffies_to_msecs(const unsigned long j);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user