From ebe78873c0adc00e13e96dd96820b6d2b4e3f109 Mon Sep 17 00:00:00 2001 From: shaun Date: Sat, 30 Dec 2017 01:26:31 -0500 Subject: [PATCH 1/9] Update example.c without the wait the 40 tasks will not have time to complete --- example.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/example.c b/example.c index 0ac638f..e53d280 100644 --- a/example.c +++ b/example.c @@ -13,16 +13,11 @@ #include #include +#include #include "thpool.h" - -void task1(){ - printf("Thread #%u working on task1\n", (int)pthread_self()); -} - - -void task2(){ - printf("Thread #%u working on task2\n", (int)pthread_self()); +void task(void *arg){ + printf("Thread #%u working on %d\n", (int)pthread_self(), (int) arg); } @@ -33,11 +28,11 @@ int main(){ puts("Adding 40 tasks to threadpool"); int i; - for (i=0; i<20; i++){ - thpool_add_work(thpool, (void*)task1, NULL); - thpool_add_work(thpool, (void*)task2, NULL); + for (i=0; i<40; i++){ + thpool_add_work(thpool, (void*)task, (void*)(uintptr_t)i); }; + thpool_wait(thpool); puts("Killing threadpool"); thpool_destroy(thpool); From 35a6d7427b50831a76a6cdc3f354396a311f3e18 Mon Sep 17 00:00:00 2001 From: Erik Janssen Date: Thu, 6 Dec 2018 21:35:50 +0100 Subject: [PATCH 2/9] Fixed wrong check for malloc result, as found with cppcheck --- thpool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thpool.c b/thpool.c index f5696f0..065182c 100644 --- a/thpool.c +++ b/thpool.c @@ -282,7 +282,7 @@ int thpool_num_threads_working(thpool_* thpool_p){ static int thread_init (thpool_* thpool_p, struct thread** thread_p, int id){ *thread_p = (struct thread*)malloc(sizeof(struct thread)); - if (thread_p == NULL){ + if (*thread_p == NULL){ err("thread_init(): Could not allocate memory for thread\n"); return -1; } From fe540f09b9149fb88ff325548baa42e11ea2b43b Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Mon, 20 Jul 2020 18:00:26 +0200 Subject: [PATCH 3/9] Cleaned up design doc --- docs/Design.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/Design.md b/docs/Design.md index 68450ad..c45394b 100644 --- a/docs/Design.md +++ b/docs/Design.md @@ -1,47 +1,47 @@ ## High level - + Description: Library providing a threading pool where you can add work on the fly. The number of threads in the pool is adjustable when creating the pool. In most cases this should equal the number of threads supported by your cpu. - + For an example on how to use the threadpool, check the main.c file or just read the documentation found in the README.md file. - + In this header file a detailed overview of the functions and the threadpool's logical - scheme is presented in case you wish to tweak or alter something. - - - - _______________________________________________________ + scheme is presented in case you wish to tweak or alter something. + + + + _______________________________________________________ / \ - | JOB QUEUE | job1 | job2 | job3 | job4 | .. | + | JOB QUEUE | job1 | job2 | job3 | job4 | .. | | | | threadpool | thread1 | thread2 | .. | \_______________________________________________________/ - - + + Description: Jobs are added to the job queue. Once a thread in the pool - is idle, it is assigned with the first job from the queue(and - erased from the queue). It's each thread's job to read from - the queue serially(using lock) and executing each job + is idle, it is assigned the first job from the queue (and that job is + erased from the queue). It is each thread's job to read from + the queue serially (using lock) and executing each job until the queue is empty. - - + + Scheme: - - thpool______ jobqueue____ ______ + + thpool______ jobqueue____ ______ | | | | .----------->|_job0_| Newly added job | | | rear ----------' |_job1_| | jobqueue----------------->| | |_job2_| - | | | front ----------. |__..__| + | | | front ----------. |__..__| |___________| |___________| '----------->|_jobn_| Job for thread to take - - - job0________ + + + job0________ | | | function----> | | | arg-------> - | | job1________ + | | job1________ | next-------------->| | |___________| | |.. From 06d4b0411b2099cb6a302766c232e54eb2ceee33 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Mon, 20 Jul 2020 18:02:06 +0200 Subject: [PATCH 4/9] Cleaned up FAQ doc --- docs/FAQ.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index a82c3f0..0af0589 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,7 +1,7 @@ +### Why isn't `pthread_exit()` used to exit a thread? -###Why isn't pthread_exit() used to exit a thread? -`thread_do` used to use pthread_exit(). However that resulted in -hard times of testing for memory leaks. The reason is that on pthread_exit() +`thread_do` used to use `pthread_exit()`. However that resulted in +hard times of testing for memory leaks. The reason is that on `pthread_exit()` not all memory is freed bt pthread (probably for future threads or false belief that the application is terminating). For these reasons a simple return is used. @@ -9,27 +9,28 @@ is used. Interestingly using `pthread_exit()` results in much more memory being allocated. -###Why do you use sleep() after calling thpool_destroy()? -This is needed only in the tests. The reason is that if you call thpool_destroy -and then exit immedietely, maybe the program will exit before all the threads +### Why do you use `sleep()` after calling `thpool_destroy()`? + +This is needed only in the tests. The reason is that if you call `thpool_destroy()` +and then exit immediately, maybe the program will exit before all the threads had the time to deallocate. In that way it is impossible to check for memory leaks. -In production you don't have to worry about this since if you call exit, -immedietely after you destroyied the pool, the threads will be freed -anyway by the OS. If you eitherway destroy the pool in the middle of your +In production you don't have to worry about this since if you call `exit()`, +immediately after you destroyed the pool, the threads will be freed +anyway by the OS. If you anyway destroy the pool in the middle of your program it doesn't matter again since the program will not exit immediately and thus threads will have more than enough time to terminate. +### Why does `wait()` use all my CPU? -###Why does wait() use all my CPU? -Notice: As of 11-Dec-2015 wait() doesn't use polling anymore. Instead a conditional variable is being used so in theory there should not be any CPU overhead. +Notice: As of 11-Dec-2015 `wait()` doesn't use polling anymore. Instead a conditional variable is being used so in theory there should not be any CPU overhead. Normally `wait()` will spike CPU usage to full when called. This is normal as long as it doesn't last for more than 1 second. The reason this happens is that `wait()` goes through various phases of polling (what is called smart polling). * Initially there is no interval between polling and hence the 100% use of your CPU. * After that the polling interval grows exponentially. * Finally after x seconds, if there is still work, polling falls back to a very big interval. - + The reason `wait()` works in this way, is that the function is mostly used when someone wants to wait for some calculation to finish. So if the calculation is assumed to take a long time then we don't want to poll too often. Still we want to poll fast in case the calculation is a simple one. To solve these two problems, this seemingly awkward behaviour is present. From 2a549a6613ceece79732eee20768ad77b6ef3834 Mon Sep 17 00:00:00 2001 From: Manos Date: Mon, 20 Jul 2020 17:31:40 +0100 Subject: [PATCH 5/9] Add .circleci/config.yml --- .circleci/config.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..01c267c --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,13 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference +version: 2.1 +# Use a package of configuration called an orb. +orbs: + # Declare a dependency on the welcome-orb + welcome: circleci/welcome-orb@0.4.1 +# Orchestrate or schedule a set of jobs +workflows: + # Name the workflow "welcome" + welcome: + # Run the welcome/run job in its own container + jobs: + - welcome/run \ No newline at end of file From 3da0ca585ebb8d1180f6a1066df55fbe3d77cfbc Mon Sep 17 00:00:00 2001 From: "Manos S.H" Date: Mon, 20 Jul 2020 19:54:18 +0100 Subject: [PATCH 6/9] Update circleci config --- .circleci/config.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 01c267c..786ede6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,13 +1,19 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference version: 2.1 -# Use a package of configuration called an orb. -orbs: - # Declare a dependency on the welcome-orb - welcome: circleci/welcome-orb@0.4.1 -# Orchestrate or schedule a set of jobs + +jobs: + test: + docker: + - image: gcc:9.2 + steps: + - checkout + - run: + name: Test + command: | + cd tests/ + ./normal_compile.sh + ./optimized_compile.sh + workflows: - # Name the workflow "welcome" - welcome: - # Run the welcome/run job in its own container + test: jobs: - - welcome/run \ No newline at end of file + - test From b0d528d7ae07074eccad3a01fbfcbd80aa0e59de Mon Sep 17 00:00:00 2001 From: "Manos S.H" Date: Mon, 20 Jul 2020 20:31:32 +0100 Subject: [PATCH 7/9] Run tests in custom docker container --- .circleci/Dockerfile | 4 ++++ .circleci/README.md | 4 ++++ .circleci/config.yml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .circleci/Dockerfile create mode 100644 .circleci/README.md diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile new file mode 100644 index 0000000..5b3193c --- /dev/null +++ b/.circleci/Dockerfile @@ -0,0 +1,4 @@ +FROM ubuntu + +RUN apt-get update && \ + apt-get -y install gcc valgrind time python diff --git a/.circleci/README.md b/.circleci/README.md new file mode 100644 index 0000000..fa77c85 --- /dev/null +++ b/.circleci/README.md @@ -0,0 +1,4 @@ +Build and push container + + docker build -t pithikos/test-c-thread-pool . + docker push pithikos/test-c-thread-pool diff --git a/.circleci/config.yml b/.circleci/config.yml index 786ede6..26df327 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 jobs: test: docker: - - image: gcc:9.2 + - image: pithikos/test-c-thread-pool steps: - checkout - run: From c0f8973cf62d5faca9c412d72c0af81c1766f201 Mon Sep 17 00:00:00 2001 From: "Manos S.H" Date: Mon, 20 Jul 2020 20:39:49 +0100 Subject: [PATCH 8/9] Update badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 694a56a..1240bf7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Build status](http://178.62.170.124:3000/pithikos/c-thread-pool/badge/?branch=master) +[![CircleCI](https://circleci.com/gh/Pithikos/C-Thread-Pool.svg?style=svg)](https://circleci.com/gh/Pithikos/C-Thread-Pool) # C Thread Pool From b4f1a6494e6457641d885ad8699546afb02ac528 Mon Sep 17 00:00:00 2001 From: "Manos S.H" Date: Tue, 21 Jul 2020 00:54:13 +0100 Subject: [PATCH 9/9] Make CI faster --- tests/memleaks.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/memleaks.sh b/tests/memleaks.sh index b85dac3..397d500 100755 --- a/tests/memleaks.sh +++ b/tests/memleaks.sh @@ -62,7 +62,12 @@ test_thread_free 8 test_thread_free 1 test_thread_free 20 test_thread_free_multi 4 20 -test_thread_free_multi 3 1000 -test_thread_free_multi 100 100 + +# test_thread_free_multi 3 1000 # Takes way too long +test_thread_free_multi 3 200 + +# test_thread_free_multi 100 100 # Takes way too long +test_thread_free_multi 100 20 + echo "No memory leaks"