使用RT_PREEMPT linux的ARM Cortex A57(ARMv8)上的浮点寄存器损坏

时间:2018-10-05 02:44:07

标签: c linux real-time arm64 armv8

我有一个在ARM Cortex A57(ARMv8)上的RT_PREEMPT linux上运行的多线程用户空间应用程序。 linux版本是4.14.0,带有相应的RT_PREEMPT补丁。以下代码是重新创建问题的简化版本。当使用优化级别-O1和更高的级别编译代码时,一段时间后错误就消失了,第24行的fl_val中有随机值(thr_fn中的乘积结果)。查看编译的汇编代码并通过gdb后,请注意,在第21行循环开始之前,将0.002的值加载到浮点寄存器(s8)中。然后,将s8寄存器的值与在第24行存储frand值的寄存器相乘。在随机时间,s8中的值具有垃圾值,并且进程按预期中止。看起来,在内核上下文切换期间,它没有正确地重新存储浮点寄存器的值。在相同硬件的相同版本的非RT内核上,相同的代码可以正常工作而没有任何错误。

我的问题

1)我应该在RT_PREEMPT内核中设置与浮点相关的内核设置吗?我已将eagerfpu = on设置为默认值(即使默认情况下处于启用状态)

2)正在阅读有关Cortex-M4的“延迟堆叠”,但不确定是否适用于Cortex A57

任何评论将不胜感激。

-------测试代码--------------------------

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdint>
  4 #include <ctime>
  5 #include <random>
  6 #include <pthread.h>
  7 #include <string.h>
  8 #include <errno.h>
  9 #include <unistd.h>
 10 #include <signal.h>
 11 
 12 #define MAX_THR 30
 13 
 14 typedef float float32_t;
 15 int32_t gflag = 0;
 16 
 17 void *thr_fn(void *arg) {
 18   //pthread_t cur_tid = pthread_self();
 19   std::random_device rd;   // non-deterministic generator
 20   std::mt19937 gen(rd());
 21   while (1) {
 22     uint32_t rand_num = gen() % 1000;
 23     float32_t frand = static_cast<float32_t>(rand_num);
 24     float32_t fl_val = (frand * 0.002F);
 25     if ((fl_val < 0.0F) || (fl_val > 2.0F)) {
 26       gflag = -1;
 27       // Keep sleeping till the process gets aborted by the main thread
 28       while(1){usleep(2000);}
 29     }
 30     usleep(1000);
 31   }
 32 }
 33 
 34 int main() {
 35   int thr_cnt;
 36   int res = 0;
 37   pthread_t tid;
 38   for (thr_cnt = 0; thr_cnt < MAX_THR; thr_cnt++) {
 39     res = pthread_create(&tid,  NULL, thr_fn, NULL);
 40     if (res != 0) {
 41       std::cout <<"Error creating pthread: " <<strerror(errno);
 42     }
 43   }
 44   while(1){
 45     if (gflag != 0) {
 46       kill(getpid(), SIGABRT);
 47     }
 48     usleep(1000 * 1000 * 1);
 49   }
 50   return (0);
 51 }

0 个答案:

没有答案