Tag: atomic

在linux驱动程序中定期调用spi_write

我正在为LCD显示器编写驱动程序。 根据应用笔记,我需要定期向命令写一个伪SPI写,以最大化其对比度。 为此,我设置了一个定时器,并尝试从定时器处理程序中编写对比度最大化的2字节伪命令。 但是,出现问题是因为s​​pi_write函数导致完整的内核崩溃并出现以下错误: BUG: scheduling while atomic: swapper/1/0/0x00000102 基于以下post: 如何解决“BUG:调度而primefaces:swapper / 0x00000103 / 0,CPU#0”? 在TSC2007驱动程序? “primefaces调度”表示你试图在某个你不应该睡觉的地方睡觉 – 就像在受自旋锁保护的关键部分或中断处理程序中一样。 也许对spi_write的调用会触发某种睡眠行为。 禁止在这里睡觉是有意义的,因为基于堆栈跟踪,我看到代码处于软IRQ状态: [] (schedule_timeout) from [] (wait_for_common+0x114/0x15c) [] (wait_for_common) from [] (spi_sync+0x70/0x88) [] (spi_sync) from [] (plt_lcd_send_toggle_comin_cmd+0x7c/0x84 [plt_lcd_spi]) [] (plt_lcd_send_toggle_comin_cmd [plt_lcd_spi]) from [] (plt_lcd_timer_handler+0xc/0x2c [plt_lcd_spi]) [] (plt_lcd_timer_handler [plt_lcd_spi]) from [] (call_timer_fn.isra.26+0x20/0x30) [] (call_timer_fn.isra.26) from [] (run_timer_softirq+0x1ec/0x21c) […]

__sync_val_compare_and_swap vs __sync_bool_compare_and_swap

我一直在考虑这两个函数的返回值。 __sync_bool_compare_and_swap函数的返回值似乎有明显的好处,即我可以用它来判断交换操作是否发生。 但是我看不到__sync_val_compare_and_swap的返回值。 首先,让我们有一个函数签名供参考(来自GCC docs减去var args): type __sync_val_compare_and_swap (type *ptr, type oldval type newval); 我看到的问题是__sync_val_compare_and_swap的返回值是* ptr的旧值。 确切地说,一旦适当的记忆障碍得以实施,这是该function的实施所看到的价值。 我明确说明了这一点,以满足在调用__sync_val_compare_and_swap和执行指令以强制执行内存屏障之间的事实,* ptr的值可能很容易改变。 现在,当函数返回该返回值时我能做什么? 尝试将它与* ptr进行比较是没有意义的,因为现在可以在其他线程上更改* ptr。 同样地比较newval和* ptr对我来说也没有什么帮助(除非我锁定* ptr,这可能首先破坏了我对primefaces的使用)。 所以我真正要做的就是询问返回值是否= = oldval,这是否有效(参见下面的警告)询问交换操作是否发生。 所以我本来可以使用__sync_bool_compare_and_swap。 我刚才提到的警告是,我在这里看到的唯一细微差别是,这样做并不能告诉我交换是否发生,它只是告诉我在内存屏障释放之前的某个时刻* ptr有相同的值为newval。 我正在考虑oldval == newval的可能性(虽然我很难看到一种有效实现函数的方法,以便它可以先检查这些值,如果它们是相同的则不交换,所以它可能是一个没有实际意义的点)。 但是我看不出这样一种情况,即知道这种差异会对我在呼叫站点产生影响。 事实上,我无法想象我会将oldval和newval设置为相等的情况。 我的问题是: 是否存在使用__sync_val_compare_and_swap和__sync_bool_compare_and_swap不等效的用例,即是否存在提供比另一个更多信息的情况? 在旁边 我之所以考虑这个问题,是因为我发现__sync_val_compare_and_swap的实现方式与sync_bool_compare_and_swap有竞争: inline int32_t __sync_val_compare_and_swap(volatile int32_t* ptr, int32_t oldval, int32_t newval) { int32_t ret = *ptr; […]

fwriteprimefaces?

一个简单的问题: 我需要在我的程序中添加一些日志记录。 如果两个进程在同一个文件上使用“fwrite”但文件描述符不同,那么写入的日志消息将是primefaces的或混合的。 有长度限制吗? 是否定义了ANSI-C行为或实现定义? 如果后来MacOSX,Linux和Windows MSVC上有什么?

volatile是一种在C / C ++中使单个字节成为primefaces的正确方法吗?

我知道volatile不会在int上强制执行primefaces性,但是如果你访问单个字节会这样做吗? 如果我没记错的话,语义要求写入和读取始终来自内存。 或者换句话说:CPU是否始终以primefaces方式读写字节?

为什么GCC填充这个位域?

程序在C中使用std = c99,这是在64位机器上。 struct epochs { volatile unsigned int epoch : 1; volatile unsigned int pulse : 1; volatile unsigned int active0 : 7; volatile unsigned int active1 : 7; volatile unsigned int counter0 : 24; volatile unsigned int counter1 : 24; }; 当我检查sizeof(epochs)它给了我12。 我可以告诉gcc不要通过添加__attribute((packed))来填充它; 所以我可以解决它。 但是我真的想知道为什么要添加4个字节来填充这个64位结构? 这里的主要内容是这个结构需要64位,因为它在64位primefaces交换操作中一次更新,当然这对12字节值不起作用。

在CUDA内核操作中添加Atomic的一些问题

我的kernel.cu类有问题 调用nvcc -v kernel.cu -o kernel.o我收到此错误: kernel.cu(17): error: identifier “atomicAdd” is undefined 我的代码: #include “dot.h” #include #include “device_functions.h” //might call atomicAdd __global__ void dot (int *a, int *b, int *c){ __shared__ int temp[THREADS_PER_BLOCK]; int index = threadIdx.x + blockIdx.x * blockDim.x; temp[threadIdx.x] = a[index] * b[index]; __syncthreads(); if( 0 == threadIdx.x ){ int sum = […]