mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
userland: move some multithreaded examples from cpp-cheat
Using them mostly to evaluate how well the emulators are handling user mode multithreading.
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
/* Count to infinity with 1 second sleep between each increment.
|
||||
*
|
||||
* https://github.com/cirosantilli/linux-kernel-module-cheat#unistd-h
|
||||
*
|
||||
* Sample application: https://cirosantilli.com/linux-kernel-module-cheat#gdb-step-debug-userland-custom-init
|
||||
*/
|
||||
|
||||
|
||||
29
userland/posix/count_to.c
Normal file
29
userland/posix/count_to.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Count up to a given number 1 second sleep between each increment.
|
||||
*
|
||||
* https://github.com/cirosantilli/linux-kernel-module-cheat#unistd-h
|
||||
*
|
||||
* We need a separate program for this from count.c because count.c
|
||||
* is also usable as an init process, where we can't control the CLI
|
||||
* arguments very well.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
unsigned long i, max;
|
||||
if (argc > 1) {
|
||||
max = strtoll(argv[1], NULL, 0);
|
||||
} else {
|
||||
max = 1;
|
||||
}
|
||||
i = 0;
|
||||
while (i < max) {
|
||||
printf("%lu\n", i);
|
||||
i++;
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
90
userland/posix/pthread_count.c
Normal file
90
userland/posix/pthread_count.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* count to infinity in n threads.
|
||||
*
|
||||
* Useful if you need to keep several threads around
|
||||
* to test something.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ....
|
||||
* ./pthread_count.out 3
|
||||
* ....
|
||||
*
|
||||
* Sample output:
|
||||
*
|
||||
* ....
|
||||
* 0 0
|
||||
* 1 0
|
||||
* 2 0
|
||||
* 1 1
|
||||
* 2 1
|
||||
* 0 1
|
||||
* 1 2
|
||||
* 0 2
|
||||
* 2 2
|
||||
* ....
|
||||
*
|
||||
* Initial motivation: confirm that:
|
||||
*
|
||||
* ....
|
||||
* ./pthread_count.out 4 &
|
||||
* cat /proc/$!/status | grep -E '^Threads:'
|
||||
* kill $!
|
||||
* ....
|
||||
*
|
||||
* shows the right thread count:
|
||||
*
|
||||
* ....
|
||||
* Threads: 5
|
||||
* ....
|
||||
*
|
||||
* which is 1 main thread + 4 we spawned!
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void* main_thread(void *arg) {
|
||||
unsigned long i = 0;
|
||||
unsigned int thread_id;
|
||||
thread_id = *((unsigned int*)arg);
|
||||
while (1) {
|
||||
printf("%u %lu\n", thread_id, i);
|
||||
i++;
|
||||
sleep(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
pthread_t *threads;
|
||||
unsigned int nthreads, i, *thread_args;
|
||||
if (argc > 1) {
|
||||
nthreads = strtoll(argv[1], NULL, 0);
|
||||
} else {
|
||||
nthreads = 1;
|
||||
}
|
||||
threads = malloc(nthreads * sizeof(*threads));
|
||||
thread_args = malloc(nthreads * sizeof(*thread_args));
|
||||
for (i = 0; i < nthreads; ++i) {
|
||||
thread_args[i] = i;
|
||||
assert(pthread_create(
|
||||
&threads[i],
|
||||
NULL,
|
||||
main_thread,
|
||||
(void*)&thread_args[i]
|
||||
) == 0);
|
||||
}
|
||||
for (i = 0; i < nthreads; ++i) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
free(thread_args);
|
||||
free(threads);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
105
userland/posix/pthread_self.c
Normal file
105
userland/posix/pthread_self.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/* Spawn N threads that print their TID with pthread_self and other
|
||||
* ID-like information for multiple threads.
|
||||
*
|
||||
* https://github.com/cirosantilli/linux-kernel-module-cheat#pthreads
|
||||
*
|
||||
* Sample usage:
|
||||
*
|
||||
* ....
|
||||
* ./pthread_tid.out 4
|
||||
* ....
|
||||
*
|
||||
* Sample output:
|
||||
*
|
||||
* ....
|
||||
* 0 tid: 139852943714048
|
||||
* tid, getpid(), pthread_self() = 0, 13709, 139852943714048
|
||||
* tid, getpid(), pthread_self() = 1, 13709, 139852935321344
|
||||
* 1 tid: 139852935321344
|
||||
* 2 tid: 139852926928640
|
||||
* tid, getpid(), pthread_self() = 2, 13709, 139852926928640
|
||||
* 3 tid: 139852918535936
|
||||
* tid, getpid(), pthread_self() = 3, 13709, 139852918535936
|
||||
* ....
|
||||
*
|
||||
* Note how the PID is the same for all threads.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void* main_thread(void *arg) {
|
||||
int argument;
|
||||
argument = *((int*)arg);
|
||||
printf(
|
||||
"tid, getpid(), pthread_self() = "
|
||||
"%d, %ju, %ju\n",
|
||||
argument,
|
||||
(uintmax_t)getpid(),
|
||||
(uintmax_t)pthread_self()
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
pthread_t *threads;
|
||||
unsigned int nthreads, i, *thread_args;
|
||||
int rc;
|
||||
|
||||
/* CLI arguments. */
|
||||
if (argc > 1) {
|
||||
nthreads = strtoll(argv[1], NULL, 0);
|
||||
} else {
|
||||
nthreads = 1;
|
||||
}
|
||||
threads = malloc(nthreads * sizeof(*threads));
|
||||
thread_args = malloc(nthreads * sizeof(*thread_args));
|
||||
|
||||
/* main thread for comparison. */
|
||||
printf(
|
||||
"tid, getpid(), pthread_self() = "
|
||||
"main, %ju, %ju\n",
|
||||
(uintmax_t)getpid(),
|
||||
(uintmax_t)pthread_self()
|
||||
);
|
||||
|
||||
/* Create all threads */
|
||||
for (i = 0; i < nthreads; ++i) {
|
||||
thread_args[i] = i;
|
||||
rc = pthread_create(
|
||||
&threads[i],
|
||||
NULL,
|
||||
main_thread,
|
||||
(void*)&thread_args[i]
|
||||
);
|
||||
if (rc != 0) {
|
||||
errno = rc;
|
||||
perror("pthread_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
assert(rc == 0);
|
||||
printf("%d tid: %ju\n", i, (uintmax_t)threads[i]);
|
||||
}
|
||||
|
||||
/* Wait for all threads to complete */
|
||||
for (i = 0; i < nthreads; ++i) {
|
||||
rc = pthread_join(threads[i], NULL);
|
||||
if (rc != 0) {
|
||||
printf("%s\n", strerror(rc));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
free(thread_args);
|
||||
free(threads);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user