Files
mckernel/test/issues/1410+1420/C1410T01.c
Tomoki Shirasawa 4b252a990f SIGCONT: don't terminate process
Change-Id: Ib959a9e5341fda37bd055724ecb9319a469b7420
Refs: #1410
2019-12-05 07:13:56 +00:00

209 lines
4.0 KiB
C

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#ifndef PAUSE_INST
#define PAUSE_INST "pause"
#endif
#define cpu_pause() \
({ \
__asm__ __volatile__(PAUSE_INST ::: "memory"); \
})
static sem_t *sync_sem1;
static sem_t *sync_sem2;
static int *parent_core;
static int *sync_flag;
#define CHILD_DONE 1
#define PARENT_DONE 2
static int *child_count;
static void child_func(void)
{
pid_t pid = getpid();
printf("[child] pid = %d\n", pid);
for (;;) {
*sync_flag = CHILD_DONE;
while (*sync_flag != PARENT_DONE) {
cpu_pause();
}
(*child_count)++;
cpu_pause();
}
}
static void parent_func(void)
{
pid_t pid;
int i = 0;
pid = getpid();
printf("[parent] pid = %d\n", pid);
for (;;) {
*sync_flag = PARENT_DONE;
while (*sync_flag != CHILD_DONE) {
cpu_pause();
}
printf("[parent] loop ok. (%d)\n", i);
if (*child_count != -1) {
printf("[child] loop ok. (%d)\n", *child_count);
}
else {
return;
}
i++;
cpu_pause();
}
}
int main(int argc, char *argv[])
{
pid_t pid = 0;
/* get shared memory */
sync_sem1 = (sem_t *)mmap(NULL, sizeof(sem_t),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
sync_sem2 = (sem_t *)mmap(NULL, sizeof(sem_t),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
parent_core = (int *)mmap(NULL, sizeof(int),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
sync_flag = (int *)mmap(NULL, sizeof(int),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
child_count = (int *)mmap(NULL, sizeof(int),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*parent_core = 0;
*sync_flag = 0;
*child_count = 0;
/* semaphore init */
sem_init(sync_sem1, 1, 0);
sem_init(sync_sem2, 1, 0);
/* create child process */
pid = fork();
switch (pid) {
case -1:
/* fork() error. */
perror("fork()");
return -1;
case 0: {
/* child process */
/* before migrate, get cpunum */
int old_mycore = sched_getcpu();
int new_mycore = -1;
printf("[child] running core %d\n", old_mycore);
/* sync parent */
sem_post(sync_sem1);
/* sync parent */
sem_wait(sync_sem2);
/* after migrate, get cpunum */
new_mycore = sched_getcpu();
/* corenum check. */
if (*parent_core != old_mycore) {
printf("[child] before migrate prevcore "
"%d, nowcore %d\n", old_mycore, new_mycore);
if (old_mycore == new_mycore) {
printf("TP failed, "
"not migrate child process.\n");
exit(-1);
}
} else {
printf("[child] migrate not required.\n");
}
/* loop */
child_func();
/* unmap */
munmap(sync_sem1, sizeof(sem_t));
munmap(sync_sem2, sizeof(sem_t));
munmap(parent_core, sizeof(int));
munmap(sync_flag, sizeof(int));
munmap(child_count, sizeof(int));
/* child exit */
exit(-1);
break;
}
default: {
/* parent process */
cpu_set_t cpuset;
int result = -1;
/* sync child */
sem_wait(sync_sem1);
/* parent corenum get */
*parent_core = sched_getcpu();
/* child process to migrate parent core */
printf("[parent] running core %d\n", *parent_core);
printf("[parent] child process migrate/bind "
"to core %d\n", *parent_core);
CPU_ZERO(&cpuset);
CPU_SET(*parent_core, &cpuset);
result = sched_setaffinity(pid, sizeof(cpuset), &cpuset);
if (result == -1) {
printf("errno = %d\n", errno);
break;
}
/* parent core bind */
printf("[parent] parent process bind "
"to core %d\n", *parent_core);
result = sched_setaffinity(0, sizeof(cpuset), &cpuset);
if (result == -1) {
printf("errno = %d\n", errno);
break;
}
/* sync child */
sem_post(sync_sem2);
/* loop */
parent_func();
/* unmap */
munmap(sync_sem1, sizeof(sem_t));
munmap(sync_sem2, sizeof(sem_t));
munmap(parent_core, sizeof(int));
munmap(sync_flag, sizeof(int));
munmap(child_count, sizeof(int));
break;
}
}
/* never return */
printf("RESULT: NG.\n");
return 0;
}