am 94926f8c: Merge "support _POSIX_REALTIME_SIGNALS"

* commit '94926f8cfa0adf37c4e19256ade7261a97f72e51':
  support _POSIX_REALTIME_SIGNALS
This commit is contained in:
Yabin Cui 2014-12-09 20:17:05 +00:00 committed by Android Git Automerger
commit e0601bd49f
17 changed files with 403 additions and 24 deletions

View file

@ -204,8 +204,11 @@ libc_bionic_src_files := \
bionic/signalfd.cpp \
bionic/sigpending.cpp \
bionic/sigprocmask.cpp \
bionic/sigqueue.cpp \
bionic/sigsuspend.cpp \
bionic/sigtimedwait.cpp \
bionic/sigwait.cpp \
bionic/sigwaitinfo.cpp \
bionic/socket.cpp \
bionic/stat.cpp \
bionic/statvfs.cpp \

View file

@ -223,6 +223,7 @@ int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
int __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t) all
int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t) all
int __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all
int __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all
# sockets

View file

@ -0,0 +1,14 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
mov ip, r7
ldr r7, =__NR_rt_sigqueueinfo
swi #0
mov r7, ip
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno_internal
END(__rt_sigqueueinfo)

View file

@ -0,0 +1,15 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
mov x8, __NR_rt_sigqueueinfo
svc #0
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno_internal
ret
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

View file

@ -0,0 +1,19 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
.set noreorder
.cpload t9
li v0, __NR_rt_sigqueueinfo
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
la t9,__set_errno_internal
j t9
nop
.set reorder
END(__rt_sigqueueinfo)

View file

@ -0,0 +1,26 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
.set push
.set noreorder
li v0, __NR_rt_sigqueueinfo
syscall
bnez a3, 1f
move a0, v0
j ra
nop
1:
move t0, ra
bal 2f
nop
2:
.cpsetup ra, t1, 2b
LA t9,__set_errno_internal
.cpreturn
j t9
move ra, t0
.set pop
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

View file

@ -0,0 +1,31 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_rel_offset ebx, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ecx, 0
pushl %edx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset edx, 0
mov 16(%esp), %ebx
mov 20(%esp), %ecx
mov 24(%esp), %edx
movl $__NR_rt_sigqueueinfo, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno_internal
addl $4, %esp
1:
popl %edx
popl %ecx
popl %ebx
ret
END(__rt_sigqueueinfo)

View file

@ -0,0 +1,16 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(__rt_sigqueueinfo)
movl $__NR_rt_sigqueueinfo, %eax
syscall
cmpq $-MAX_ERRNO, %rax
jb 1f
negl %eax
movl %eax, %edi
call __set_errno_internal
1:
ret
END(__rt_sigqueueinfo)
.hidden __rt_sigqueueinfo

46
libc/bionic/sigqueue.cpp Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*);
int sigqueue(pid_t pid, int signo, const sigval value) {
siginfo_t info;
memset(&info, 0, sizeof(siginfo_t));
info.si_signo = signo;
info.si_code = SI_QUEUE;
info.si_pid = getpid();
info.si_uid = getuid();
info.si_value = value;
return __rt_sigqueueinfo(pid, signo, &info);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <signal.h>
#include "private/kernel_sigset_t.h"
extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
int sigtimedwait(const sigset_t* set, siginfo_t* info, const timespec* timeout) {
kernel_sigset_t sigset(set);
return __rt_sigtimedwait(sigset.get(), info, timeout, sizeof(sigset));
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <signal.h>
int sigwaitinfo(const sigset_t* set, siginfo_t* info) {
return sigtimedwait(set, info, NULL);
}

View file

@ -69,7 +69,7 @@
#define _POSIX_PRIORITIZED_IO -1 /* not implemented */
#define _POSIX_RAW_SOCKETS 200809L
#define _POSIX_READER_WRITER_LOCKS 200809L
#define _POSIX_REALTIME_SIGNALS -1 /* for now, this is not supported */
#define _POSIX_REALTIME_SIGNALS 200809L
#define _POSIX_REGEXP 1
#define _POSIX_RE_DUP_MAX 255
#define _POSIX_SAVED_IDS 1 /* saved user ids is a Linux feature */

View file

@ -32,6 +32,7 @@
#include <asm/sigcontext.h>
#include <errno.h>
#include <limits.h>
#include <linux/time.h>
#include <machine/pthread_types.h>
#include <string.h>
#include <sys/cdefs.h>
@ -133,6 +134,10 @@ extern void psignal(int, const char*);
extern int pthread_kill(pthread_t, int);
extern int pthread_sigmask(int, const sigset_t*, sigset_t*);
extern int sigqueue(pid_t, int, const union sigval);
extern int sigtimedwait(const sigset_t*, siginfo_t*, const struct timespec*);
extern int sigwaitinfo(const sigset_t*, siginfo_t*);
__END_DECLS
#endif /* _SIGNAL_H_ */

View file

@ -18,17 +18,27 @@
#define _BIONIC_TESTS_SCOPED_SIGNAL_HANDLER_H
#include <signal.h>
#include <string.h>
class ScopedSignalHandler {
public:
ScopedSignalHandler(int signal_number, void (*handler)(int), int sa_flags = 0)
: signal_number_(signal_number) {
sigemptyset(&action_.sa_mask);
memset(&action_, 0, sizeof(action_));
action_.sa_flags = sa_flags;
action_.sa_handler = handler;
sigaction(signal_number_, &action_, &old_action_);
}
ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*),
int sa_flags = SA_SIGINFO)
: signal_number_(signal_number) {
memset(&action_, 0, sizeof(action_));
action_.sa_flags = sa_flags;
action_.sa_sigaction = action;
sigaction(signal_number_, &action_, &old_action_);
}
~ScopedSignalHandler() {
sigaction(signal_number_, &old_action_, NULL);
}

View file

@ -178,17 +178,34 @@ static void* IdFn(void* arg) {
return arg;
}
static void* SleepFn(void* arg) {
sleep(reinterpret_cast<uintptr_t>(arg));
return NULL;
}
static void* SpinFn(void* arg) {
volatile bool* b = reinterpret_cast<volatile bool*>(arg);
while (!*b) {
class SpinFunctionHelper {
public:
SpinFunctionHelper() {
SpinFunctionHelper::spin_flag_ = true;
}
return NULL;
}
~SpinFunctionHelper() {
UnSpin();
}
auto GetFunction() -> void* (*)(void*) {
return SpinFunctionHelper::SpinFn;
}
void UnSpin() {
SpinFunctionHelper::spin_flag_ = false;
}
private:
static void* SpinFn(void*) {
while (spin_flag_) {}
return NULL;
}
static volatile bool spin_flag_;
};
// It doesn't matter if spin_flag_ is used in several tests,
// because it is always set to false after each test. Each thread
// loops on spin_flag_ can find it becomes false at some time.
volatile bool SpinFunctionHelper::spin_flag_ = false;
static void* JoinFn(void* arg) {
return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), NULL));
@ -229,8 +246,10 @@ TEST(pthread, pthread_create_EAGAIN) {
}
TEST(pthread, pthread_no_join_after_detach) {
SpinFunctionHelper spinhelper;
pthread_t t1;
ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5)));
ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
// After a pthread_detach...
ASSERT_EQ(0, pthread_detach(t1));
@ -241,10 +260,10 @@ TEST(pthread, pthread_no_join_after_detach) {
}
TEST(pthread, pthread_no_op_detach_after_join) {
bool done = false;
SpinFunctionHelper spinhelper;
pthread_t t1;
ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done));
ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
// If thread 2 is already waiting to join thread 1...
pthread_t t2;
@ -256,7 +275,7 @@ TEST(pthread, pthread_no_op_detach_after_join) {
ASSERT_EQ(0, pthread_detach(t1));
AssertDetached(t1, false);
done = true;
spinhelper.UnSpin();
// ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
void* join_result;
@ -369,8 +388,10 @@ TEST(pthread, pthread_setname_np__self) {
}
TEST(pthread, pthread_setname_np__other) {
SpinFunctionHelper spinhelper;
pthread_t t1;
ASSERT_EQ(0, pthread_create(&t1, NULL, SleepFn, reinterpret_cast<void*>(5)));
ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
ASSERT_EQ(0, pthread_setname_np(t1, "short 2"));
}
@ -451,8 +472,10 @@ TEST(pthread, pthread_detach__leak) {
}
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
SpinFunctionHelper spinhelper;
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, NULL, SleepFn, reinterpret_cast<void*>(5)));
ASSERT_EQ(0, pthread_create(&t, NULL, spinhelper.GetFunction(), NULL));
clockid_t c;
ASSERT_EQ(0, pthread_getcpuclockid(t, &c));
@ -501,10 +524,10 @@ TEST(pthread, pthread_kill__no_such_thread) {
}
TEST(pthread, pthread_join__multijoin) {
bool done = false;
SpinFunctionHelper spinhelper;
pthread_t t1;
ASSERT_EQ(0, pthread_create(&t1, NULL, SpinFn, &done));
ASSERT_EQ(0, pthread_create(&t1, NULL, spinhelper.GetFunction(), NULL));
pthread_t t2;
ASSERT_EQ(0, pthread_create(&t2, NULL, JoinFn, reinterpret_cast<void*>(t1)));
@ -514,7 +537,7 @@ TEST(pthread, pthread_join__multijoin) {
// Multiple joins to the same thread should fail.
ASSERT_EQ(EINVAL, pthread_join(t1, NULL));
done = true;
spinhelper.UnSpin();
// ...but t2's join on t1 still goes ahead (which we can tell because our join on t2 finishes).
void* join_result;

View file

@ -16,9 +16,10 @@
#include <signal.h>
#include <errno.h>
#include <gtest/gtest.h>
#include <errno.h>
#include "ScopedSignalHandler.h"
static size_t SIGNAL_MIN() {
@ -276,3 +277,101 @@ TEST(signal, limits) {
// We don't currently reserve any at the top.
ASSERT_EQ(SIGRTMAX, __SIGRTMAX);
}
static int g_sigqueue_signal_handler_call_count = 0;
static void SigqueueSignalHandler(int signum, siginfo_t* info, void*) {
ASSERT_EQ(SIGALRM, signum);
ASSERT_EQ(SIGALRM, info->si_signo);
ASSERT_EQ(SI_QUEUE, info->si_code);
ASSERT_EQ(1, info->si_value.sival_int);
++g_sigqueue_signal_handler_call_count;
}
TEST(signal, sigqueue) {
ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
sigval_t sigval;
sigval.sival_int = 1;
errno = 0;
ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
ASSERT_EQ(0, errno);
ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
}
TEST(signal, sigwaitinfo) {
// Block SIGALRM.
sigset_t just_SIGALRM;
sigemptyset(&just_SIGALRM);
sigaddset(&just_SIGALRM, SIGALRM);
sigset_t original_set;
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
// Raise SIGALRM.
sigval_t sigval;
sigval.sival_int = 1;
ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
// Get pending SIGALRM.
siginfo_t info;
errno = 0;
ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info));
ASSERT_EQ(0, errno);
ASSERT_EQ(SIGALRM, info.si_signo);
ASSERT_EQ(1, info.si_value.sival_int);
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
}
TEST(signal, sigtimedwait) {
// Block SIGALRM.
sigset_t just_SIGALRM;
sigemptyset(&just_SIGALRM);
sigaddset(&just_SIGALRM, SIGALRM);
sigset_t original_set;
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
// Raise SIGALRM.
sigval_t sigval;
sigval.sival_int = 1;
ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
// Get pending SIGALRM.
siginfo_t info;
struct timespec timeout;
timeout.tv_sec = 2;
timeout.tv_nsec = 0;
errno = 0;
ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout));
ASSERT_EQ(0, errno);
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
}
static int64_t NanoTime() {
struct timespec t;
t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &t);
return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
}
TEST(signal, sigtimedwait_timeout) {
// Block SIGALRM.
sigset_t just_SIGALRM;
sigemptyset(&just_SIGALRM);
sigaddset(&just_SIGALRM, SIGALRM);
sigset_t original_set;
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
// Wait timeout.
int64_t start_time = NanoTime();
siginfo_t info;
struct timespec timeout;
timeout.tv_sec = 0;
timeout.tv_nsec = 1000000;
errno = 0;
ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout));
ASSERT_EQ(EAGAIN, errno);
ASSERT_GE(NanoTime() - start_time, 1000000);
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
}

View file

@ -556,6 +556,7 @@ TEST(unistd, _POSIX_macros_smoke) {
EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
EXPECT_GT(_POSIX_REGEXP, 0);
EXPECT_GT(_POSIX_RE_DUP_MAX, 0);
EXPECT_GT(_POSIX_SAVED_IDS, 0);
@ -617,7 +618,6 @@ TEST(unistd, _POSIX_macros_smoke) {
EXPECT_EQ(-1, _POSIX_BARRIERS);
EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO);
EXPECT_EQ(-1, _POSIX_REALTIME_SIGNALS);
EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS);
EXPECT_EQ(-1, _POSIX_SPAWN);
EXPECT_EQ(-1, _POSIX_SPIN_LOCKS);
@ -704,6 +704,7 @@ TEST(unistd, sysconf) {
VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK_RANGE);
VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMORY_PROTECTION);
VERIFY_SYSCONF_POSIX_VERSION(_SC_PRIORITY_SCHEDULING);
VERIFY_SYSCONF_POSIX_VERSION(_SC_REALTIME_SIGNALS);
VERIFY_SYSCONF_POSIX_VERSION(_SC_SEMAPHORES);
VERIFY_SYSCONF_POSIX_VERSION(_SC_SYNCHRONIZED_IO);
VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMERS);
@ -778,7 +779,6 @@ TEST(unistd, sysconf) {
VERIFY_SYSCONF_NOT_SUPPORT(_SC_BARRIERS);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_MESSAGE_PASSING);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_PRIORITIZED_IO);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_REALTIME_SIGNALS);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_SHARED_MEMORY_OBJECTS);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_SPAWN);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_SPIN_LOCKS);