编译器内存障碍会产生影响,迫使编译器确保缓存在寄存器中的所有堆栈变量都在屏障之前写入内存.
例如,GCC有以下声明:
asm inline ("" : : : "memory");
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉编译器(特别是GCC,但我也对其他人感兴趣)只对特定变量做同样的效果?类似于以下想象的构造:
int x;
...
asm inline ("" : : : "memory(x)");
Run Code Online (Sandbox Code Playgroud)
具有预期的行为,即x和x的值仅被写入相应的存储器位置,如果它恰好被缓存在寄存器中.
原因是我有一个特定的变量,我需要确保它不会缓存在寄存器中,以便硬件引擎可以读取它的值.但是,完整的编译器内存屏障将强制编译器向内存写入在该时间点可能缓存在寄存器中的所有其他变量的值,这可能相当于我需要编写的更多数据.我想知道是否有更具体的东西.
提前致谢!
请考虑以下代码:
#include <stdlib.h>
#ifndef TRY
#define TRY struct
#endif
TRY testme
{
int one;
int two;
char three;
int four;
};
int
main (void)
{
{
volatile TRY testme one;
one.one = 2;
one.three = 7;
}
{
volatile TRY testme twos;
twos.one = 3;
}
{
volatile TRY testme one;
one.one = 4;
}
{
volatile TRY testme twos;
twos.one = 5;
}
{
volatile TRY testme twos;
twos.one = 6;
}
{
volatile TRY testme twos;
twos.one = …Run Code Online (Sandbox Code Playgroud) 我有一个内联函数定义,它包装了一个内联程序集。我希望根据参数在构建时是否已知的事实来选择不同的内联汇编实现。
我的问题是如何在 C 代码或内联汇编中询问地址值在构建时是否已知,因此适合作为立即值。如果您正在考虑 __builtin_constant_p - 请继续阅读。
这是一些说明我的意图的代码:我正在尝试找到一种方法来实现“is_immediate”。
static char arr[5];
void __attribute__((always_inline)) do_something(char * buf)
{
if(is_immediate(buf) {
// Argument is constant, can use immediate form
asm volatile ("insn1 %0" : : "i"(buf));
} else {
// Argument is computed at runtime, use a register
unsigned long tmp = (unsigned long)buf + 1;
asm volatile("insn2 %0" : : "r"(tmp));
}
int main(void)
{
do_something(&arr);
}
Run Code Online (Sandbox Code Playgroud)
乍一看,__builtin_constant_p() 似乎正是所需的魔法,但它不起作用。
不起作用的原因是,虽然在链接器将数组放入内存并为其选择地址后就知道数组的地址(因此它确实符合内联汇编的直接约束),但它不是在链接之前的编译时已知。
因此,我正在寻找一种方法来询问“这个变量是否适合作为立即值?” 而不是“这是一个常量表达式吗?”。
我编写了内核模块,它执行nf_register_hook并使用字符设备机制将抓取的数据包通过设备读取挂钩获取到用户空间.我使用全局缓冲区和缓冲区变量,这就是为什么我需要在新数据包到来或用户阅读我的设备时锁定它.我使用了splinlock_irqsave和spin_unlock_irqrestore(&locker,flags),但是我的模块陷入死锁并且系统死机.
unsigned int main_hook(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int(*okfn)(struct sk_buff*)) {
unsigned long flags;
spin_lock_irqsave(&locker,flags);
...
spin_unlock_irqrestore(&locker,flags);
}
ssize_t sniffer_dev_read(struct file *filep, char *buff, size_t count, loff_t *offp) {
spin_lock_irqsave(&locker,flags);
...
spin_unlock_irqrestore(&locker,flags);
}
main_hook is registered in nf_register_hook()
sniffer_dev_read is registered in register_chrdev
Run Code Online (Sandbox Code Playgroud)
当用户从设备读取时,系统进入死锁状态.想法?或者可能是irq保存/恢复与netfiler hook/char设备读取不兼容,我必须在这里使用特殊锁定?
我想使用sysfs在用户空间上使用GPIO中断.我使用这些命令:
[root@at91]:gpio109 > echo 109 > export
[root@at91]:gpio109 > cd gpio109/
[root@at91]:gpio109 > ll
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 direction
drwxr-xr-x 2 root 0 0 Jan 1 00:17 power
lrwxrwxrwx 1 root 0 0 Jan 1 00:17 subsystem -> ../../gpio
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 uevent
-rw-r--r-- 1 root 0 4096 Jan 1 00:17 value
Run Code Online (Sandbox Code Playgroud)
gpio运行良好,但我无法使用中断.我到处读到我必须有一个边缘文件来轮询这个文件.但在我的系统上,此文件不存在.我做了很多尝试找到解决方案,但仍然没有成功.
我的目标是Linux内核2.6.30上的AT91SAM9263.
在我的电路板启动时,我收到了关于中断的消息:
AT91: 160 gpio irqs in 5 banks
Run Code Online (Sandbox Code Playgroud)
这表明该功能at91_gpio_irq_setup()执行得很好.
你知道吗?
请考虑以下x86代码示例:
#include <stdlib.h>
static int i;
static inline __attribute__((always_inline)) test(int x)
{
asm volatile("mov %1, %0" : "=r"(i): "i"(x));
}
int main(void)
{
test(5);
return i;
}
Run Code Online (Sandbox Code Playgroud)
如果我用它构建它:
gcc -O test.c
Run Code Online (Sandbox Code Playgroud)
它建立得很好.
如果我用它构建它(没有优化):
gcc test.c
Run Code Online (Sandbox Code Playgroud)
它在组装阶段失败,因为该值'5'不会作为直接值传播到内联函数测试,因此我们使约束失败.
我希望能够在不启用其他非相关优化的情况下编译此代码,以便更轻松地进行调试.
从理论上讲,-O它只是一个捷径,可以在GCC手册中记录一系列GCC优化选项.不幸的是,我无法找到打开此行为的特定GCC标志.
有任何想法吗?
澄清:为了减轻任何疑问,代码片段只是一个例子.除了展示我想要做的事情之外,它本身并没有多大意义.实际的用例涉及一个自定义处理器上的指令,该指令只能立即作为我试图在C结构中包装的参数.一个宏确实可以做到这一点,但是遭受了宏的所有通常的缺点,因此我试图避免它.
更新:对于那些想知道的人,一个宏也不会工作.似乎内联函数根本不起作用.例如,这也不起作用:
void foo (void)
{
int i = 6;
asm volatile ("" : : "i" (i));
}
Run Code Online (Sandbox Code Playgroud)
我还修正了问题标题以反映这一点.
c gcc inline-assembly compiler-optimization compiler-options
我正在尝试建立一个Android源代码的私有存储库,同时在github上托管git树作为私有存储库.
我没有问题将manifest.xml文件改为指向github上托管的公共git树,就像CynagonMod一样,但是当试图指向私有repos时,我在尝试"repo sync"时遇到以下错误:
初始化项目用户名/ android_external_webkit ...
致命:远程端意外挂断
错误:无法获取用户名/ android_external_webkit
其中username/android_external_webkit当然是同名的私有github仓库.
我理解错误发生,因为我没有为github指定我的用户名和凭据,但是我没有看到如何在带repo的manifest.xml中执行此操作.
有任何想法吗?
谢谢!吉拉德