Format code automatically for regression tests

This commit is contained in:
Ruihan Li
2024-03-16 00:15:19 +08:00
committed by Tate, Hongliang Tian
parent 60cd65d837
commit 82de200d03
22 changed files with 1344 additions and 1123 deletions

View File

@ -157,6 +157,7 @@ docs: $(CARGO_OSDK)
.PHONY: format .PHONY: format
format: format:
@./tools/format_all.sh @./tools/format_all.sh
@make --no-print-directory -C regression format
.PHONY: check .PHONY: check
check: $(CARGO_OSDK) check: $(CARGO_OSDK)
@ -175,6 +176,7 @@ check: $(CARGO_OSDK)
@for dir in $(OSDK_CRATES); do \ @for dir in $(OSDK_CRATES); do \
(cd $$dir && cargo osdk clippy -- -- -D warnings) || exit 1; \ (cd $$dir && cargo osdk clippy -- -- -D warnings) || exit 1; \
done done
@make --no-print-directory -C regression check
.PHONY: clean .PHONY: clean
clean: clean:

View File

@ -120,6 +120,14 @@ $(EXT2_IMAGE):
.PHONY: build .PHONY: build
build: $(INITRAMFS_IMAGE) $(EXT2_IMAGE) build: $(INITRAMFS_IMAGE) $(EXT2_IMAGE)
.PHONY: format
format:
@make --no-print-directory -C apps format
.PHONY: check
check:
@make --no-print-directory -C apps check
.PHONY: clean .PHONY: clean
clean: clean:
@rm -rf $(BUILD_DIR) @rm -rf $(BUILD_DIR)

View File

@ -0,0 +1,125 @@
# SPDX-License-Identifier: GPL-2.0
#
# This file was copied from Linux kernel, or more precisely, from:
#
# https://github.com/torvalds/linux/blob/e5eb28f6d1afebed4bb7d740a797d0390bd3a357/.clang-format
#
# We have removed the long but useless `ForEachMacros` option.
# clang-format configuration file. Intended for clang-format >= 11.
#
# For more information, see:
#
# Documentation/process/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 8
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
# Taken from git's rules
PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatementsExceptForEachMacros
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 8
UseTab: Always
...

View File

@ -1,12 +1,17 @@
# SPDX-License-Identifier: MPL-2.0 # SPDX-License-Identifier: MPL-2.0
MAKEFLAGS += --no-builtin-rules # Prevent the implicit rules from compiling ".c" or ".s" files automatically. MAKEFLAGS += --no-builtin-rules # Prevent the implicit rules from compiling ".c" or ".s" files automatically.
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH))) CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
INITRAMFS ?= $(CUR_DIR)/../build/initramfs INITRAMFS ?= $(CUR_DIR)/../build/initramfs
REGRESSION_BUILD_DIR ?= $(INITRAMFS)/regression REGRESSION_BUILD_DIR ?= $(INITRAMFS)/regression
TEST_APPS := signal_c pthread network hello_world hello_pie hello_c fork_c fork execve pty TEST_APPS := signal_c pthread network hello_world hello_pie hello_c fork_c fork execve pty
C_SOURCES := $(shell find . -type f \( -name "*.c" -or -name "*.h" \) )
.PHONY: all .PHONY: all
all: $(TEST_APPS) scripts all: $(TEST_APPS) scripts
@ -14,6 +19,16 @@ all: $(TEST_APPS) scripts
$(TEST_APPS): $(TEST_APPS):
@make --no-print-directory -C $@ @make --no-print-directory -C $@
.PHONY: format
format:
@echo "Fixing code format for regression tests..."
@clang-format -i $(C_SOURCES)
.PHONY: check
check:
@echo "Checking code format for regression tests..."
@clang-format --dry-run --Werror $(C_SOURCES)
$(REGRESSION_BUILD_DIR): $(REGRESSION_BUILD_DIR):
@mkdir -p $@ @mkdir -p $@

View File

@ -3,7 +3,8 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
int main() { int main()
{
char *argv[] = { "argv1", "argv2", NULL }; char *argv[] = { "argv1", "argv2", NULL };
char *envp[] = { "home=/", "version=1.1", NULL }; char *envp[] = { "home=/", "version=1.1", NULL };
// The hello will be put at /execve/hello in InitRamfs // The hello will be put at /execve/hello in InitRamfs

View File

@ -2,7 +2,8 @@
#include <stdio.h> #include <stdio.h>
int main(int argc, char *argv[], char *envp[]) { int main(int argc, char *argv[], char *envp[])
{
printf("Hello world from hello.c(execved in execve.c)!\n"); printf("Hello world from hello.c(execved in execve.c)!\n");
printf("argc = %d\n", argc); printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++) { for (int i = 0; i < argc; i++) {

View File

@ -3,7 +3,8 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
int main() { int main()
{
printf("before fork\n"); printf("before fork\n");
fflush(stdout); fflush(stdout);
if (fork() == 0) { if (fork() == 0) {

View File

@ -2,7 +2,8 @@
#include <stdio.h> #include <stdio.h>
int main() { int main()
{
printf("hello world from hello_c!\n"); printf("hello world from hello_c!\n");
return 0; return 0;
} }

View File

@ -2,7 +2,8 @@
#include <stdio.h> #include <stdio.h>
int main() { int main()
{
printf("hello world from hello_pie!\n"); printf("hello world from hello_pie!\n");
return 0; return 0;
} }

View File

@ -8,7 +8,8 @@
#define MESG1 "Hello from child" #define MESG1 "Hello from child"
#define MESG2 "Hello from parent" #define MESG2 "Hello from parent"
int main() { int main()
{
int sockets[2], child; int sockets[2], child;
char buf[1024]; char buf[1024];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {

View File

@ -7,7 +7,8 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <unistd.h> #include <unistd.h>
int main() { int main()
{
int sockfd; int sockfd;
int option; int option;
@ -21,28 +22,33 @@ int main() {
// Get send buffer size // Get send buffer size
int sendbuf; int sendbuf;
socklen_t sendbuf_len = sizeof(sendbuf); socklen_t sendbuf_len = sizeof(sendbuf);
if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuf, &sendbuf_len) < 0 || sendbuf_len != sizeof(sendbuf)) { if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuf, &sendbuf_len) <
0 ||
sendbuf_len != sizeof(sendbuf)) {
perror("Getting SO_SNDBUF option failed"); perror("Getting SO_SNDBUF option failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int error; int error;
socklen_t error_len = sizeof(error); socklen_t error_len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &error_len ) < 0 || error_len != sizeof(error) || error != 0) { if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &error_len) < 0 ||
error_len != sizeof(error) || error != 0) {
perror("Getting SO_SNDBUF option failed"); perror("Getting SO_SNDBUF option failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Disable Nagle algorithm // Disable Nagle algorithm
option = 1; option = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) < 0) { if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &option,
sizeof(option)) < 0) {
perror("Setting TCP_NODELAY option failed"); perror("Setting TCP_NODELAY option failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Enable reuse addr // Enable reuse addr
option = 1; option = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0) { if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option,
sizeof(option)) < 0) {
perror("Setting SO_REUSEADDR option failed"); perror("Setting SO_REUSEADDR option failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -50,14 +56,18 @@ int main() {
// Print new value // Print new value
int nagle; int nagle;
socklen_t nagle_len = sizeof(nagle); socklen_t nagle_len = sizeof(nagle);
if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &nagle, &nagle_len) < 0 || nagle != 1) { if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &nagle, &nagle_len) <
0 ||
nagle != 1) {
perror("Getting TCP_NODELAY option failed."); perror("Getting TCP_NODELAY option failed.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int reuseaddr; int reuseaddr;
socklen_t reuseaddr_len = sizeof(reuseaddr); socklen_t reuseaddr_len = sizeof(reuseaddr);
if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, &reuseaddr_len) < 0 || reuseaddr != 1) { if (getsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
&reuseaddr_len) < 0 ||
reuseaddr != 1) {
perror("Getting SO_REUSEADDR option failed."); perror("Getting SO_REUSEADDR option failed.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -8,7 +8,8 @@
#define PORT 8080 #define PORT 8080
int main() { int main()
{
int sock = 0, valread; int sock = 0, valread;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
char *hello = "Hello from client"; char *hello = "Hello from client";
@ -30,7 +31,8 @@ int main() {
} }
// Connect to the server // Connect to the server
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
0) {
printf("\n Connection Failed \n"); printf("\n Connection Failed \n");
return -1; return -1;
} }

View File

@ -8,7 +8,8 @@
#define PORT 8080 #define PORT 8080
int main() { int main()
{
int server_fd, new_socket, valread; int server_fd, new_socket, valread;
struct sockaddr_in address; struct sockaddr_in address;
int opt = 1; int opt = 1;
@ -23,7 +24,8 @@ int main() {
} }
// Set socket options // Set socket options
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
sizeof(opt))) {
perror("setsockopt failed"); perror("setsockopt failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -51,7 +53,8 @@ int main() {
} }
// Accept the connection // Accept the connection
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t *)&addrlen)) < 0) {
perror("accept failed"); perror("accept failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -12,7 +12,8 @@
#define SERVER_PORT 1234 #define SERVER_PORT 1234
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
int main() { int main()
{
int sock_fd; int sock_fd;
char buffer[BUFFER_SIZE]; char buffer[BUFFER_SIZE];
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
@ -34,7 +35,9 @@ int main() {
// Send massage to server // Send massage to server
const char *message = "Hello world from udp client!"; const char *message = "Hello world from udp client!";
if (sendto(sock_fd, message, strlen(message), 0, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { if (sendto(sock_fd, message, strlen(message), 0,
(const struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0) {
perror("sendto failed"); perror("sendto failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -43,12 +46,15 @@ int main() {
struct sockaddr_in sender_addr; struct sockaddr_in sender_addr;
socklen_t sender_len = sizeof(sender_addr); socklen_t sender_len = sizeof(sender_addr);
int recv_len; int recv_len;
if ((recv_len = recvfrom(sock_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&sender_addr, &sender_len)) < 0) { if ((recv_len = recvfrom(sock_fd, buffer, BUFFER_SIZE, 0,
(struct sockaddr *)&sender_addr,
&sender_len)) < 0) {
perror("recvfrom failed"); perror("recvfrom failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
buffer[recv_len] = '\0'; buffer[recv_len] = '\0';
printf("Received %s from %s:%d\n", buffer, inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port)); printf("Received %s from %s:%d\n", buffer,
inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port));
// close socket // close socket
close(sock_fd); close(sock_fd);

View File

@ -12,7 +12,8 @@
#define SERVER_PORT 1234 #define SERVER_PORT 1234
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
int main() { int main()
{
int sock_fd; int sock_fd;
char buffer[BUFFER_SIZE]; char buffer[BUFFER_SIZE];
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
@ -33,9 +34,8 @@ int main() {
} }
// Bind to server address // Bind to server address
if (bind(sock_fd, (struct sockaddr*)&serv_addr, if (bind(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
sizeof(serv_addr)) 0) {
< 0) {
perror("bind failed"); perror("bind failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -44,16 +44,21 @@ int main() {
struct sockaddr_in sender_addr; struct sockaddr_in sender_addr;
socklen_t sender_len = sizeof(sender_addr); socklen_t sender_len = sizeof(sender_addr);
int recv_len; int recv_len;
if ((recv_len = recvfrom(sock_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&sender_addr, &sender_len)) < 0) { if ((recv_len = recvfrom(sock_fd, buffer, BUFFER_SIZE, 0,
(struct sockaddr *)&sender_addr,
&sender_len)) < 0) {
perror("recvfrom failed"); perror("recvfrom failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
buffer[recv_len] = '\0'; buffer[recv_len] = '\0';
printf("Received %s from %s:%d\n", buffer, inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port)); printf("Received %s from %s:%d\n", buffer,
inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port));
/// Send message to client /// Send message to client
const char *message = "Hello world from udp server!"; const char *message = "Hello world from udp server!";
if (sendto(sock_fd, message, strlen(message), 0, (const struct sockaddr *)&sender_addr, sizeof(sender_addr)) < 0) { if (sendto(sock_fd, message, strlen(message), 0,
(const struct sockaddr *)&sender_addr,
sizeof(sender_addr)) < 0) {
perror("sendto failed"); perror("sendto failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -11,7 +11,8 @@
#define SOCKET_NAME "/tmp/test.sock" #define SOCKET_NAME "/tmp/test.sock"
#define BUFFER_SIZE 128 #define BUFFER_SIZE 128
int main() { int main()
{
int client_fd, len; int client_fd, len;
struct sockaddr_un server_addr, peer_addr; struct sockaddr_un server_addr, peer_addr;
char buf[BUFFER_SIZE]; char buf[BUFFER_SIZE];
@ -26,16 +27,18 @@ int main() {
// Connect Server // Connect Server
memset(&server_addr, 0, sizeof(server_addr)); memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX; server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1); strncpy(server_addr.sun_path, SOCKET_NAME,
sizeof(server_addr.sun_path) - 1);
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { if (connect(client_fd, (struct sockaddr *)&server_addr,
sizeof(server_addr)) == -1) {
perror("connect"); perror("connect");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int addrlen = sizeof(peer_addr); int addrlen = sizeof(peer_addr);
int rc = getpeername(client_fd, (struct sockaddr *)&peer_addr, int rc =
&addrlen); getpeername(client_fd, (struct sockaddr *)&peer_addr, &addrlen);
if (rc == -1) { if (rc == -1) {
perror("getpeername"); perror("getpeername");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -11,7 +11,8 @@
#define SOCKET_NAME "/tmp/test.sock" #define SOCKET_NAME "/tmp/test.sock"
#define BUFFER_SIZE 128 #define BUFFER_SIZE 128
int main() { int main()
{
int server_fd, accepted_fd, len; int server_fd, accepted_fd, len;
struct sockaddr_un server_addr, client_addr; struct sockaddr_un server_addr, client_addr;
char buf[BUFFER_SIZE]; char buf[BUFFER_SIZE];
@ -26,9 +27,11 @@ int main() {
// 绑定Socket地址 // 绑定Socket地址
memset(&server_addr, 0, sizeof(server_addr)); memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX; server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1); strncpy(server_addr.sun_path, SOCKET_NAME,
sizeof(server_addr.sun_path) - 1);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { if (bind(server_fd, (struct sockaddr *)&server_addr,
sizeof(server_addr)) == -1) {
perror("bind"); perror("bind");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -20,9 +20,12 @@
// Helper functions // Helper functions
// ============================================================================ // ============================================================================
#define THROW_ERROR(fmt, ...) do { \ #define THROW_ERROR(fmt, ...) \
printf("\t\tERROR:" fmt " in func %s at line %d of file %s with errno %d: %s\n", \ do { \
##__VA_ARGS__, __func__, __LINE__, __FILE__, errno, strerror(errno)); \ printf("\t\tERROR:" fmt \
" in func %s at line %d of file %s with errno %d: %s\n", \
##__VA_ARGS__, __func__, __LINE__, __FILE__, errno, \
strerror(errno)); \
return -1; \ return -1; \
} while (0) } while (0)
@ -30,7 +33,6 @@
// Helper macros // Helper macros
// ============================================================================ // ============================================================================
#define NTHREADS (3) #define NTHREADS (3)
#define STACK_SIZE (8 * 1024) #define STACK_SIZE (8 * 1024)
@ -48,7 +50,8 @@ struct thread_arg {
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
}; };
static void *thread_func(void *_arg) { static void *thread_func(void *_arg)
{
struct thread_arg *arg = _arg; struct thread_arg *arg = _arg;
for (long i = 0; i < arg->local_count; i++) { for (long i = 0; i < arg->local_count; i++) {
pthread_mutex_lock(arg->mutex); pthread_mutex_lock(arg->mutex);
@ -58,7 +61,8 @@ static void *thread_func(void *_arg) {
return NULL; return NULL;
} }
static int test_mutex_with_concurrent_counter(void) { static int test_mutex_with_concurrent_counter(void)
{
/* /*
* Multiple threads are to increase a global counter concurrently * Multiple threads are to increase a global counter concurrently
*/ */
@ -80,7 +84,8 @@ static int test_mutex_with_concurrent_counter(void) {
thread_arg->global_count = &global_count; thread_arg->global_count = &global_count;
thread_arg->mutex = &mutex; thread_arg->mutex = &mutex;
if (pthread_create(&threads[ti], NULL, thread_func, thread_arg) < 0) { if (pthread_create(&threads[ti], NULL, thread_func,
thread_arg) < 0) {
printf("ERROR: pthread_create failed (ti = %d)\n", ti); printf("ERROR: pthread_create failed (ti = %d)\n", ti);
return -1; return -1;
} }
@ -119,7 +124,8 @@ struct thread_robust_arg {
int ret_err = -1; int ret_err = -1;
static void *thread_worker(void *_arg) { static void *thread_worker(void *_arg)
{
struct thread_robust_arg *arg = _arg; struct thread_robust_arg *arg = _arg;
int err = pthread_mutex_lock(arg->mutex); int err = pthread_mutex_lock(arg->mutex);
if (err == EOWNERDEAD) { if (err == EOWNERDEAD) {
@ -143,7 +149,8 @@ static void *thread_worker(void *_arg) {
return NULL; return NULL;
} }
static int test_robust_mutex_with_concurrent_counter(void) { static int test_robust_mutex_with_concurrent_counter(void)
{
volatile int global_count = 0; volatile int global_count = 0;
pthread_t threads[NTHREADS]; pthread_t threads[NTHREADS];
struct thread_robust_arg thread_args[NTHREADS]; struct thread_robust_arg thread_args[NTHREADS];
@ -160,7 +167,8 @@ static int test_robust_mutex_with_concurrent_counter(void) {
thread_arg->global_count = &global_count; thread_arg->global_count = &global_count;
thread_arg->mutex = &mutex; thread_arg->mutex = &mutex;
if (pthread_create(&threads[ti], NULL, thread_worker, thread_arg) < 0) { if (pthread_create(&threads[ti], NULL, thread_worker,
thread_arg) < 0) {
THROW_ERROR("pthread_create failed (ti = %d)", ti); THROW_ERROR("pthread_create failed (ti = %d)", ti);
} }
} }
@ -173,15 +181,18 @@ static int test_robust_mutex_with_concurrent_counter(void) {
// printf("Thread %d joined\n", ti); // printf("Thread %d joined\n", ti);
// fflush(stdout); // fflush(stdout);
if (ret_val && *ret_val != 0) { if (ret_val && *ret_val != 0) {
THROW_ERROR("run thread failed (ti = %d) with return val: %d", ti, *ret_val); THROW_ERROR(
"run thread failed (ti = %d) with return val: %d",
ti, *ret_val);
} }
} }
// printf("Thread all exited.\n"); // printf("Thread all exited.\n");
// fflush(stdout); // fflush(stdout);
// Check the result // Check the result
if (global_count != NTHREADS) { if (global_count != NTHREADS) {
THROW_ERROR("incorrect global_count (actual = %d, expected = %d)", global_count, THROW_ERROR(
NTHREADS); "incorrect global_count (actual = %d, expected = %d)",
global_count, NTHREADS);
} }
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
@ -202,7 +213,8 @@ struct thread_cond_arg {
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
}; };
static void *thread_cond_wait(void *_arg) { static void *thread_cond_wait(void *_arg)
{
struct thread_cond_arg *arg = _arg; struct thread_cond_arg *arg = _arg;
printf("Thread #%d: start to wait on condition variable.\n", arg->ti); printf("Thread #%d: start to wait on condition variable.\n", arg->ti);
fflush(stdout); fflush(stdout);
@ -226,7 +238,8 @@ static void *thread_cond_wait(void *_arg) {
return NULL; return NULL;
} }
static int test_mutex_with_cond_wait(void) { static int test_mutex_with_cond_wait(void)
{
volatile unsigned int val = 0; volatile unsigned int val = 0;
volatile int exit_thread_count = 0; volatile int exit_thread_count = 0;
pthread_t threads[NTHREADS]; pthread_t threads[NTHREADS];
@ -244,7 +257,8 @@ static int test_mutex_with_cond_wait(void) {
thread_arg->cond_val = &cond_val; thread_arg->cond_val = &cond_val;
thread_arg->mutex = &mutex; thread_arg->mutex = &mutex;
if (pthread_create(&threads[ti], NULL, thread_cond_wait, thread_arg) < 0) { if (pthread_create(&threads[ti], NULL, thread_cond_wait,
thread_arg) < 0) {
printf("ERROR: pthread_create failed (ti = %d)\n", ti); printf("ERROR: pthread_create failed (ti = %d)\n", ti);
return -1; return -1;
} }
@ -274,7 +288,8 @@ static int test_mutex_with_cond_wait(void) {
return 0; return 0;
} }
int main() { int main()
{
test_mutex_with_concurrent_counter(); test_mutex_with_concurrent_counter();
test_robust_mutex_with_concurrent_counter(); test_robust_mutex_with_concurrent_counter();
// test_mutex_with_cond_wait(); // test_mutex_with_cond_wait();

View File

@ -7,7 +7,8 @@
#include <termios.h> #include <termios.h>
#include <pty.h> #include <pty.h>
int main() { int main()
{
int master, slave; int master, slave;
char name[256]; char name[256];
struct termios term; struct termios term;

View File

@ -24,20 +24,23 @@
// Helper functions // Helper functions
// ============================================================================ // ============================================================================
#define THROW_ERROR(fmt, ...) do { \ #define THROW_ERROR(fmt, ...) \
printf("\t\tERROR:" fmt " in func %s at line %d of file %s with errno %d: %s\n", \ do { \
##__VA_ARGS__, __func__, __LINE__, __FILE__, errno, strerror(errno)); \ printf("\t\tERROR:" fmt \
" in func %s at line %d of file %s with errno %d: %s\n", \
##__VA_ARGS__, __func__, __LINE__, __FILE__, errno, \
strerror(errno)); \
return -1; \ return -1; \
} while (0) } while (0)
// ============================================================================ // ============================================================================
// Test sigprocmask // Test sigprocmask
// ============================================================================ // ============================================================================
#define sigcmpset(a, b) memcmp((a), (b), 8) #define sigcmpset(a, b) memcmp((a), (b), 8)
int test_sigprocmask() { int test_sigprocmask()
{
int ret; int ret;
sigset_t new, old; sigset_t new, old;
sigset_t expected_old; sigset_t expected_old;
@ -102,9 +105,11 @@ int test_sigprocmask() {
#define MAX_RECURSION_LEVEL 3 #define MAX_RECURSION_LEVEL 3
static void handle_sigio(int num, siginfo_t *info, void *context) { static void handle_sigio(int num, siginfo_t *info, void *context)
{
static volatile int recursion_level = 0; static volatile int recursion_level = 0;
printf("Hello from SIGIO signal handler (recursion_level = %d)!\n", recursion_level); printf("Hello from SIGIO signal handler (recursion_level = %d)!\n",
recursion_level);
fflush(stdout); fflush(stdout);
recursion_level++; recursion_level++;
@ -114,7 +119,8 @@ static void handle_sigio(int num, siginfo_t *info, void *context) {
recursion_level--; recursion_level--;
} }
int test_raise() { int test_raise()
{
struct sigaction new_action, old_action; struct sigaction new_action, old_action;
memset(&new_action, 0, sizeof(struct sigaction)); memset(&new_action, 0, sizeof(struct sigaction));
memset(&old_action, 0, sizeof(struct sigaction)); memset(&old_action, 0, sizeof(struct sigaction));
@ -139,7 +145,8 @@ int test_raise() {
// Test catching and handling hardware exception // Test catching and handling hardware exception
// ============================================================================ // ============================================================================
static void handle_sigfpe(int num, siginfo_t *info, void *_context) { static void handle_sigfpe(int num, siginfo_t *info, void *_context)
{
printf("SIGFPE Caught\n"); printf("SIGFPE Caught\n");
fflush(stdout); fflush(stdout);
assert(num == SIGFPE); assert(num == SIGFPE);
@ -154,13 +161,15 @@ static void handle_sigfpe(int num, siginfo_t *info, void *_context) {
// Note: this function is fragile in the sense that compiler may not always // Note: this function is fragile in the sense that compiler may not always
// emit the instruction pattern that triggers divide-by-zero as we expect. // emit the instruction pattern that triggers divide-by-zero as we expect.
// TODO: rewrite this in assembly // TODO: rewrite this in assembly
int div_maybe_zero(int x, int y) { int div_maybe_zero(int x, int y)
{
return x / y; return x / y;
} }
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m"(*(addr))) #define fxsave(addr) __asm __volatile("fxsave %0" : "=m"(*(addr)))
int test_handle_sigfpe() { int test_handle_sigfpe()
{
// Set up a signal handler that handles divide-by-zero exception // Set up a signal handler that handles divide-by-zero exception
struct sigaction new_action, old_action; struct sigaction new_action, old_action;
memset(&new_action, 0, sizeof(struct sigaction)); memset(&new_action, 0, sizeof(struct sigaction));
@ -201,11 +210,13 @@ int test_handle_sigfpe() {
} }
// TODO: rewrite this in assembly // TODO: rewrite this in assembly
int read_maybe_null(int *p) { int read_maybe_null(int *p)
{
return *p; return *p;
} }
static void handle_sigsegv(int num, siginfo_t *info, void *_context) { static void handle_sigsegv(int num, siginfo_t *info, void *_context)
{
printf("SIGSEGV Caught\n"); printf("SIGSEGV Caught\n");
fflush(stdout); fflush(stdout);
@ -221,8 +232,8 @@ static void handle_sigsegv(int num, siginfo_t *info, void *_context) {
return; return;
} }
int test_handle_sigsegv()
int test_handle_sigsegv() { {
// Set up a signal handler that handles divide-by-zero exception // Set up a signal handler that handles divide-by-zero exception
struct sigaction new_action, old_action; struct sigaction new_action, old_action;
memset(&new_action, 0, sizeof(struct sigaction)); memset(&new_action, 0, sizeof(struct sigaction));
@ -254,18 +265,21 @@ int test_handle_sigsegv() {
// ============================================================================ // ============================================================================
int sigchld = 0; int sigchld = 0;
void proc_exit() { void proc_exit()
{
sigchld = 1; sigchld = 1;
} }
int test_sigchld() { int test_sigchld()
{
signal(SIGCHLD, proc_exit); signal(SIGCHLD, proc_exit);
printf("Run a parent process has pid = %d\n", getpid()); printf("Run a parent process has pid = %d\n", getpid());
fflush(stdout); fflush(stdout);
int pid = fork(); int pid = fork();
if (pid == 0) { if (pid == 0) {
// child process // child process
printf("create a new proces successfully (pid = %d)\n", getpid()); printf("create a new proces successfully (pid = %d)\n",
getpid());
fflush(stdout); fflush(stdout);
exit(0); exit(0);
} else { } else {
@ -285,7 +299,8 @@ int test_sigchld() {
stack_t g_old_ss; stack_t g_old_ss;
static void handle_sigpipe(int num, siginfo_t *info, void *context) { static void handle_sigpipe(int num, siginfo_t *info, void *context)
{
static volatile int recursion_level = 0; static volatile int recursion_level = 0;
printf("Hello from SIGPIPE signal handler on the alternate signal stack (recursion_level = %d)\n", printf("Hello from SIGPIPE signal handler on the alternate signal stack (recursion_level = %d)\n",
recursion_level); recursion_level);
@ -304,7 +319,8 @@ static void handle_sigpipe(int num, siginfo_t *info, void *context) {
#define SIGSTACKSIZE (4 * 4096) #define SIGSTACKSIZE (4 * 4096)
int test_sigaltstack() { int test_sigaltstack()
{
static char stack[SIGSTACKSIZE]; static char stack[SIGSTACKSIZE];
stack_t expected_ss = { stack_t expected_ss = {
.ss_size = SIGSTACKSIZE, .ss_size = SIGSTACKSIZE,
@ -318,9 +334,9 @@ int test_sigaltstack() {
if (sigaltstack(NULL, &actual_ss) < 0) { if (sigaltstack(NULL, &actual_ss) < 0) {
THROW_ERROR("failed to call sigaltstack"); THROW_ERROR("failed to call sigaltstack");
} }
if (actual_ss.ss_size != expected_ss.ss_size if (actual_ss.ss_size != expected_ss.ss_size ||
|| actual_ss.ss_sp != expected_ss.ss_sp actual_ss.ss_sp != expected_ss.ss_sp ||
|| actual_ss.ss_flags != expected_ss.ss_flags) { actual_ss.ss_flags != expected_ss.ss_flags) {
THROW_ERROR("failed to check the signal stack after set"); THROW_ERROR("failed to check the signal stack after set");
} }
@ -347,7 +363,8 @@ int test_sigaltstack() {
return 0; return 0;
} }
int main() { int main()
{
test_sigprocmask(); test_sigprocmask();
test_raise(); test_raise();
test_handle_sigfpe(); test_handle_sigfpe();