描述
我正在研究一个在多核ARMv7a SoC上运行的嵌入式Linux系统(使用内核3.4和仿生,类似Android).我们有一个用户空间线程,它基本上处理来自内核的事件.事件是从IRQ生成的,必须以非常低的延迟对用户空间做出反应.
线程以SCHED_FIFO优先级0运行.它是系统中唯一的优先级0线程.线程的近似代码:
while (1)
{
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN|POLLRDNORM|POLLPRI;
int ret = poll(fds, 1, reallyLongTimeout);
FTRACE("poll() exit");
if (ret > 0)
{
// notify worker threads of pending events
}
}
Run Code Online (Sandbox Code Playgroud)
通常我们会得到非常好的延迟(线程在IRQ发生的同一毫秒内完全往返于poll()),然而随机我们有几十毫秒的延迟会破坏一切.在遍历整个地方之后,我得出结论,延迟发生在IRQ触发之后和poll()系统调用返回之前,因为线程使自己处于睡眠状态.然后一段时间后被一些未知的力量唤醒,一切都继续.
我怀疑其他一些IRQ但是在启用了sched:,irq : , timer:*tracing我不得不排除它.我在移植系统调用时遇到了一些困难:*跟踪器到ARM内核.系统调用跟踪器工作,但如果我也启用sched:*我在ring_buffer代码中得到各种各样的恐慌.
在sys_poll()中插入一些自定义跟踪点之后,我得到了一个令人不舒服的结论,即我的线程在sys_poll()返回之后但在它重新出现在用户空间之前就已经睡着了.
这是带有我在fs/select.c中的自定义跟踪点的带注释的跟踪:
<my thread>-915 [001] ...1 17.589394: custom: do_poll:786 - calling do_pollfd
<my thread>-915 [001] ...1 17.589399: custom: do_poll:794 - failed, no events
<my thread>-915 [001] ...1 17.589402: custom: do_poll:823 - going to sleep, count = …
Run Code Online (Sandbox Code Playgroud) multithreading multicore linux-kernel embedded-linux low-latency
这是我的问题:我需要管理我的程序无法读取或写入的远程连续缓冲区中的内存.它需要具有malloc()/ free()语义,并支持设置最小对齐和碎片避免(尽可能).由于我无法直接读取或写入此缓冲区,因此我需要使用本地结构来管理所有分配.
我已经在使用boost了,所以如果可以按摩内部的东西来做到这一点,那就太好了.但是,我并不反对使用C库或类似的东西.
举个例子,我需要一个非IPC版本的:
boost::interprocess::basic_managed_external_buffer<
char,
boost::interprocess::rbtree_best_fit<
boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void>,
SOME_ALIGNMENT>,
boost::interprocess::iset_index>
Run Code Online (Sandbox Code Playgroud)
最好使用malloc/free语义而不是new/delete但是没有实际读取或写入底层缓冲区(并将所有分配信息/数据结构保存在单独的缓冲区中)
有任何想法吗?
PS我不希望boost :: interprocess示例误导,我只是熟悉接口,所以以它为例.应用程序实际上不是进程间的,分配器只能在我的应用程序中使用.
具体来说,我希望能够管理一个16GB的外部缓冲区,其分配大小从128字节一直到512MB.这是严格的64位代码,但即便如此我更喜欢指针类型作为模板参数,所以我可以明确地使用uint64_t.
我注意到scipy.misc.resize有些奇怪 - 似乎使用除"最近"之外的任何插值方法都会导致结果图像中距离(0,0)大约1x1像素偏移.
这是一个将3x3图像带到6x6的完全合成示例:
>>> src
array([[ 0., 0., 0.],
[ 0., 64., 0.],
[ 0., 0., 0.]])
>>> imresize(src, (6, 6), interp='bicubic',mode='F')
array([[ 1., 0., -5., -8., -5., 0.],
[ 0., 0., 0., 0., 0., 0.],
[ -5., 0., 25., 40., 25., 0.],
[ -8., 0., 40., 64., 40., 0.],
[ -5., 0., 25., 40., 25., 0.],
[ 0., 0., 0., 0., 0., 0.]], dtype=float32)
>>> imresize(src, (6, 6), interp='bilinear',mode='F')
array([[ 0., 0., 0., 0., 0., 0.],
[ 0., …
Run Code Online (Sandbox Code Playgroud) 在我的C++代码中经常使用以下类型的辅助函数:
static inline std::string stringf(const char *fmt, ...)
{
std::string ret;
// Deal with varargs
va_list args;
va_start(args, fmt);
// Resize our string based on the arguments
ret.resize(vsnprintf(0, 0, fmt, args));
// End the varargs and restart because vsnprintf mucked up our args
va_end(args);
va_start(args, fmt);
// Fill the string
if(!ret.empty())
{
vsnprintf(&ret.front(), ret.size() + 1, fmt, args);
}
// End of variadic section
va_end(args);
// Return the string
return ret;
}
Run Code Online (Sandbox Code Playgroud)
它有一些上升空间:
现在,我有一些问题: