- 论坛徽章:
- 0
|
问题环境:
1、Suse10、Suse11或者的主机环境;
2、使用Qemu-1.3.0或者Qemu-1.6.0模拟realview-eb-mpcore多核的单板,Linux内核使用2.6.34.10的版本;
3、qemu启动参数:./qemu-system-arm -M realview-eb-mpcore -cpu cortex-a9 -smp 4 -m 256M -kernel zImage -initrd rootfs.bin -nographic -append "init=/linuxrc console=ttyAMA0 root=/dev/ram0"
4、测试程序:
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/wait.h>
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
#define PAGE_SIZE (4096)
unsigned int g_PageData[PAGE_SIZE] = {0};
unsigned int g_index = 4096;
void SetAffinityByCpu(pid_t tPid, int iCpu)
{
cpu_set_t mask;
__CPU_ZERO(&mask);
__CPU_SET(iCpu, &mask);
(void)sched_setaffinity((pid_t)tPid, sizeof(cpu_set_t), (cpu_set_t *)&mask);
return ;
}
int GetThreadID(void)
{
return (int)syscall(SYS_gettid);
}
void print_data(void)
{
int index = 0;
for (index = 0; index < 4096; index ++)
{
printf("g_PageData[%d]=%d;\r\n", index, g_PageData[index]);
}
printf("g_index=%d;\r\n", g_index);
return;
}
void SetData_Main(unsigned int data, int index)
{
if ((g_PageData[index] + 4096) != data)
{
printf("Main Data Error! pid=%d. index=%d; data=%d; g_PageData[index]=%d;\r\n",
getpid(), index, data, g_PageData[index]);
}
g_PageData[index] = data;
return;
}
void SetData_Sub(unsigned int data, int index)
{
if ((g_PageData[index] + 4096) != data)
{
printf("Sub Data Error! pid=%d. index=%d; data=%d; g_PageData[index]=%d;\r\n",
getpid(), index, data, g_PageData[index]);
}
g_PageData[index] = data;
return;
}
void SetPageData_Main(void)
{
unsigned int index;
/* 每次设置0xFFFF0000次 */
while (g_index < 0xFFFF0000)
{
SetData_Main(g_index, g_index % 4096);
g_index ++;
}
}
void SetPageData_Sub(void)
{
unsigned int index;
/* 每次设置40960000次 */
while (g_index < 0xFFFF0000)
{
SetData_Sub(g_index, g_index % 4096);
g_index ++;
}
}
void * sub_thread(void * arg)
{
pid_t sub_pid = 0;
pid_t wait_pid = 0;
pid_t self_pid = GetThreadID();
SetAffinityByCpu(self_pid , 3);
while (1)
{
sub_pid = fork();
if (0 == sub_pid)
{
int index = 0;
pid_t self_pid = GetThreadID();
printf("fork pid=%d;\r\n", self_pid);
/* 子进程重新设置 */
for (index = 0; index < 4096; index ++)
{
g_PageData[index] = index;
}
g_index = 4096;
SetPageData_Sub();
break;
}
else
{
/* parent */
wait_pid = waitpid(sub_pid, 0, 0);
}
//
while (1) sleep(1);
}
return 0;
}
int main(int argc, char * argv[])
{
int mem_times = 0;
int index = 0;
pthread_t thread;
pid_t self_pid = GetThreadID();
printf("main pid=%d;\r\n", self_pid);
SetAffinityByCpu(self_pid, 2);
/* 主进程设置为相差4096 */
for (index = 0; index < 4096; index ++)
{
g_PageData[index] = index;
}
/* 启动子线程 */
(void)pthread_create(&thread, 0, sub_thread, 0);
while (1)
{
SetPageData_Main();
}
return;
}
问题:
forkpage测试程序高概率出现主进程的数据错误的打印;
其它现象:
1、如果将qmeu 1.6编译成动态链接且不strip,或者仅strip -g时,问题不出现;
2、如果将qemu的启动参数修改成2个核时,问题不出现;
3、如果使用单核问题也不出现;
4. 真实环境上也不出现问题;
怀疑点:
Qemu在多核仿真存在内存改写或者其它BUG; |
|