CELIX-282: Update for licence info C Thread Pools
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/3a379542 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/3a379542 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/3a379542 Branch: refs/heads/develop Commit: 3a3795429f9ca8a376c16e6e3af59eded59b3cb3 Parents: a86dff7 Author: Pepijn Noltes <[email protected]> Authored: Mon Apr 11 13:42:38 2016 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Mon Apr 11 13:42:38 2016 +0200 ---------------------------------------------------------------------- LICENSE | 29 +++++++++++++++++++ utils/docs/thpool/Design.md | 52 +++++++++++++++++++++++++++++++++ utils/docs/thpool/FAQ.md | 33 +++++++++++++++++++++ utils/docs/thpool/README.md | 62 ++++++++++++++++++++++++++++++++++++++++ utils/public/docs/Design.md | 52 --------------------------------- utils/public/docs/FAQ.md | 33 --------------------- utils/public/docs/README.md | 62 ---------------------------------------- 7 files changed, 176 insertions(+), 147 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/LICENSE ---------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index 903aee1..8799560 100644 --- a/LICENSE +++ b/LICENSE @@ -302,3 +302,32 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------------- + +This product bundles C-Thread-Pool (thpool.c, thpool.h & utils/docs/thpool/*.md), +which is available under the MIT license. For more details see +https://github.com/Pithikos/C-Thread-Pool + +The MIT License (MIT) +Copyright (c) 2011-2012 MIT + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/docs/thpool/Design.md ---------------------------------------------------------------------- diff --git a/utils/docs/thpool/Design.md b/utils/docs/thpool/Design.md new file mode 100644 index 0000000..00fe1b4 --- /dev/null +++ b/utils/docs/thpool/Design.md @@ -0,0 +1,52 @@ +## 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. + + + + _______________________________________________________ + / \ + | 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 + until the queue is empty. + + + Scheme: + + thpool______ jobqueue____ ______ + | | | | .----------->|_job0_| Newly added job + | | | rear ----------' |_job1_| + | jobqueue----------------->| | |_job2_| + | | | front ----------. |__..__| + |___________| |___________| '----------->|_jobn_| Job for thread to take + + + job0________ + | | + | function----> + | | + | arg-------> + | | job1________ + | next-------------->| | + |___________| | |.. + + +## Synchronisation + +*Mutexes* and *binary semaphores* are the main tools to achieve synchronisation between threads. http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/docs/thpool/FAQ.md ---------------------------------------------------------------------- diff --git a/utils/docs/thpool/FAQ.md b/utils/docs/thpool/FAQ.md new file mode 100644 index 0000000..584a699 --- /dev/null +++ b/utils/docs/thpool/FAQ.md @@ -0,0 +1,33 @@ + +###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() +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. + +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 +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 +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? +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. http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/docs/thpool/README.md ---------------------------------------------------------------------- diff --git a/utils/docs/thpool/README.md b/utils/docs/thpool/README.md new file mode 100644 index 0000000..0a07ebc --- /dev/null +++ b/utils/docs/thpool/README.md @@ -0,0 +1,62 @@ + + +# C Thread Pool + +This is a minimal but fully functional threadpool implementation. + + * ANCI C and POSIX compliant + * Number of threads can be chosen on initialization + * Minimal but powerful interface + * Full documentation + +The threadpool is under MIT license. Notice that this project took a considerable amount of work and sacrifice of my free time and the reason I give it for free (even for commercial use) is so when you become rich and wealthy you don't forget about us open-source creatures of the night. Cheers! + + +## v2 Changes + +This is an updated and heavily refactored version of my original threadpool. The main things taken into consideration in this new version are: + + * Synchronisation control from the user (pause/resume/wait) + * Thorough testing for memory leaks and race conditions + * Cleaner and more opaque API + * Smart polling - polling interval changes on-the-fly + + +## Run an example + +The library is not precompiled so you have to compile it with your project. The thread pool +uses POSIX threads so if you compile with gcc on Linux you have to use the flag `-pthread` like this: + + gcc example.c thpool.c -D THPOOL_DEBUG -pthread -o example + + +Then run the executable like this: + + ./example + + +## Basic usage + +1. Include the header in your source file: `#include "thpool.h"` +2. Create a thread pool with number of threads you want: `threadpool thpool = thpool_init(4);` +3. Add work to the pool: `thpool_add_work(thpool, (void*)function_p, (void*)arg_p);` + +The workers(threads) will start their work automatically as fast as there is new work +in the pool. If you want to wait for all added work to be finished before continuing +you can use `thpool_wait(thpool);`. If you want to destroy the pool you can use +`thpool_destroy(thpool);`. + + + +## API + +For a deeper look into the documentation check in the [thpool.h](https://github.com/Pithikos/C-Thread-Pool/blob/master/thpool.h) file. Below is a fast practical overview. + +| Function example | Description | +|---------------------------------|---------------------------------------------------------------------| +| ***thpool_init(4)*** | Will return a new threadpool with `4` threads. | +| ***thpool_add_work(thpool, (void*)function_p, (void*)arg_p)*** | Will add new work to the pool. Work is simply a function. You can pass a single argument to the function if you wish. If not, `NULL` should be passed. | +| ***thpool_wait(thpool)*** | Will wait for all jobs (both in queue and currently running) to finish. | +| ***thpool_destroy(thpool)*** | This will destroy the threadpool. If jobs are currently being executed, then it will wait for them to finish. | +| ***thpool_pause(thpool)*** | All threads in the threadpool will pause no matter if they are idle or executing work. | +| ***thpool_resume(thpool)*** | If the threadpool is paused, then all threads will resume from where they were. | http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/public/docs/Design.md ---------------------------------------------------------------------- diff --git a/utils/public/docs/Design.md b/utils/public/docs/Design.md deleted file mode 100644 index 00fe1b4..0000000 --- a/utils/public/docs/Design.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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. - - - - _______________________________________________________ - / \ - | 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 - until the queue is empty. - - - Scheme: - - thpool______ jobqueue____ ______ - | | | | .----------->|_job0_| Newly added job - | | | rear ----------' |_job1_| - | jobqueue----------------->| | |_job2_| - | | | front ----------. |__..__| - |___________| |___________| '----------->|_jobn_| Job for thread to take - - - job0________ - | | - | function----> - | | - | arg-------> - | | job1________ - | next-------------->| | - |___________| | |.. - - -## Synchronisation - -*Mutexes* and *binary semaphores* are the main tools to achieve synchronisation between threads. http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/public/docs/FAQ.md ---------------------------------------------------------------------- diff --git a/utils/public/docs/FAQ.md b/utils/public/docs/FAQ.md deleted file mode 100644 index 584a699..0000000 --- a/utils/public/docs/FAQ.md +++ /dev/null @@ -1,33 +0,0 @@ - -###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() -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. - -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 -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 -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? -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. http://git-wip-us.apache.org/repos/asf/celix/blob/3a379542/utils/public/docs/README.md ---------------------------------------------------------------------- diff --git a/utils/public/docs/README.md b/utils/public/docs/README.md deleted file mode 100644 index 0a07ebc..0000000 --- a/utils/public/docs/README.md +++ /dev/null @@ -1,62 +0,0 @@ - - -# C Thread Pool - -This is a minimal but fully functional threadpool implementation. - - * ANCI C and POSIX compliant - * Number of threads can be chosen on initialization - * Minimal but powerful interface - * Full documentation - -The threadpool is under MIT license. Notice that this project took a considerable amount of work and sacrifice of my free time and the reason I give it for free (even for commercial use) is so when you become rich and wealthy you don't forget about us open-source creatures of the night. Cheers! - - -## v2 Changes - -This is an updated and heavily refactored version of my original threadpool. The main things taken into consideration in this new version are: - - * Synchronisation control from the user (pause/resume/wait) - * Thorough testing for memory leaks and race conditions - * Cleaner and more opaque API - * Smart polling - polling interval changes on-the-fly - - -## Run an example - -The library is not precompiled so you have to compile it with your project. The thread pool -uses POSIX threads so if you compile with gcc on Linux you have to use the flag `-pthread` like this: - - gcc example.c thpool.c -D THPOOL_DEBUG -pthread -o example - - -Then run the executable like this: - - ./example - - -## Basic usage - -1. Include the header in your source file: `#include "thpool.h"` -2. Create a thread pool with number of threads you want: `threadpool thpool = thpool_init(4);` -3. Add work to the pool: `thpool_add_work(thpool, (void*)function_p, (void*)arg_p);` - -The workers(threads) will start their work automatically as fast as there is new work -in the pool. If you want to wait for all added work to be finished before continuing -you can use `thpool_wait(thpool);`. If you want to destroy the pool you can use -`thpool_destroy(thpool);`. - - - -## API - -For a deeper look into the documentation check in the [thpool.h](https://github.com/Pithikos/C-Thread-Pool/blob/master/thpool.h) file. Below is a fast practical overview. - -| Function example | Description | -|---------------------------------|---------------------------------------------------------------------| -| ***thpool_init(4)*** | Will return a new threadpool with `4` threads. | -| ***thpool_add_work(thpool, (void*)function_p, (void*)arg_p)*** | Will add new work to the pool. Work is simply a function. You can pass a single argument to the function if you wish. If not, `NULL` should be passed. | -| ***thpool_wait(thpool)*** | Will wait for all jobs (both in queue and currently running) to finish. | -| ***thpool_destroy(thpool)*** | This will destroy the threadpool. If jobs are currently being executed, then it will wait for them to finish. | -| ***thpool_pause(thpool)*** | All threads in the threadpool will pause no matter if they are idle or executing work. | -| ***thpool_resume(thpool)*** | If the threadpool is paused, then all threads will resume from where they were. |
