我在/usr/include/linux/kernel.h中碰到了这个奇怪的宏代码:
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
Run Code Online (Sandbox Code Playgroud)
怎么:-!!
办?
我一直在挖掘Linux内核的某些部分,发现这样的调用:
if (unlikely(fd < 0))
{
/* Do something */
}
Run Code Online (Sandbox Code Playgroud)
要么
if (likely(!err))
{
/* Do something */
}
Run Code Online (Sandbox Code Playgroud)
我找到了它们的定义:
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
Run Code Online (Sandbox Code Playgroud)
我知道它们是为了优化,但它们是如何工作的?使用它们可以预期性能/尺寸减少多少?至少在瓶颈代码中(当然在用户空间中)是否值得麻烦(并且可能失去可移植性).
我注意到Linux内核代码使用bool,但我认为bool是C++类型.bool是标准C扩展(例如,ISO C90)还是GCC扩展?
Linux内核开发人员如何在本地测试代码并在提交代码之后对其进行测试?他们是否使用某种单元测试,构建自动化?测试计划?
假设硬件具有无限的性能,Linux机箱是否支持> 65536个开放的TCP连接?
据我所知,短暂端口的数量(<65536)限制了从一个本地IP到一个远程IP上的一个端口的连接数.
元组(本地ip,本地端口,远程ip,远程端口)是唯一定义TCP连接的东西; 这是否意味着如果这些参数中有多个是免费的,则可以支持超过65K的连接.例如,从多个本地IP连接到多个远程主机上的单个端口号.
系统中还有另外16位的限制吗?或许文件描述符的数量?
我正在编程服务器,似乎我的连接数量有限,因为我的带宽没有饱和,即使我已经将连接数设置为"无限制".
如何增加或消除我的Ubuntu Linux盒一次可以打开的最大连接数?操作系统是否限制了这个,还是路由器或ISP?或者是别的什么?
我读到Linux是一个单片内核.单片内核是否意味着将完整的内核代码编译并链接到可执行文件中?
如果Linux能够支持模块,为什么不将所有子系统分解为模块并在必要时加载它们?在这种情况下,内核最初不必加载所有模块,并且可以维护模块中函数的索引并在必要时加载它们.
当Linux内存不足(OOM)时,OOM杀手基于一些启发式选择一个杀死进程(这是一个有趣的读物:http://lwn.net/Articles/317814/).
如何以编程方式确定最近被OOM杀手杀死的进程?
TL; DR:如果Linux内核丢失了缓冲的I/O写入,那么应用程序是否有任何方法可以找到?
我知道你有fsync()
文件(和它的父目录)的耐用性.问题是,如果内核由于I/O错误而丢失了待写入的脏缓冲区,应用程序如何检测并恢复或中止?
想想数据库应用程序等,其中写入顺序和写入持久性可能是至关重要的.
Linux内核的模块层可以在某些情况下失去缓冲已成功提交的I/O请求write()
,pwrite()
等等,有这样的错误:
Buffer I/O error on device dm-0, logical block 12345
lost page write due to I/O error on dm-0
Run Code Online (Sandbox Code Playgroud)
(见end_buffer_write_sync(...)
和end_buffer_async_write(...)
在fs/buffer.c
).
Buffer I/O error on dev dm-0, logical block 12345, lost async page write
Run Code Online (Sandbox Code Playgroud)
由于应用程序write()
已经无错误地返回,因此似乎无法将错误报告给应用程序.
我不熟悉内核源代码,但我认为它设置AS_EIO
在缓冲区上,如果它正在执行异步写入,则无法写出:
set_bit(AS_EIO, &page->mapping->flags);
set_buffer_write_io_error(bh);
clear_buffer_uptodate(bh);
SetPageError(page);
Run Code Online (Sandbox Code Playgroud)
但是我不清楚应用程序是否或如何在以后查找fsync()
文件以确认它在磁盘上时会发现这一点.
其中计时功能,time
,clock
getrusage
,clock_gettime
,gettimeofday
和timespec_get
,我想清楚地了解它们是如何实现的,为了知道在什么情况下我必须使用他们什么是他们的返回值.
首先,我们需要对返回wall-clock值的函数进行分类,与返回进程或线程值的函数进行比较.gettimeofday
返回wall-clock值,clock_gettime
返回wall-clock值或进程或线程值,具体取决于Clock
传递给它的参数.getrusage
并clock
返回过程值.
然后第二个问题涉及这些功能的实施,因此,它们的准确性.这些功能使用哪种硬件或软件机制.
似乎getrusage
只使用内核tick(通常为1ms长),因此不能比ms更准确.这样对吗?然后该getimeofday
函数似乎使用最准确的底层硬件.因此,它的准确性通常是近期硬件上的微秒(因为API而不能更多).那么clock
,手册页谈的是"近似",它是什么意思?那么clock_gettime
,API是纳秒级,是否意味着如果底层硬件允许它,它能够如此准确?单调性怎么样?
还有其他功能吗?