GithubHelp home page GithubHelp logo

byannoni / qthreads Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 1.0 132 KB

A POSIX thread wrapper using a pool and queues of functions for C and (soon) C++

License: Apache License 2.0

C 96.17% Makefile 3.83%

qthreads's People

Contributors

byannoni avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

alexbrinister

qthreads's Issues

Change the name threading_queue

The name threading_queue is misleading. Perhaps thread_pool would be better.

  • Pick a name for the project (keep qthreads)
  • Pick a name to replace threading_queue (qtpool)
  • Pick a prefix (qt)
  • Refactor the code

fq_push() should take separate arguments

There is no reason why fq_push() should take a struct rather than creating a struct out of two arguments internally. It's a pain to set up a struct for each element by hand. New signature could be:

enum pt_error fq_push(struct function_queue*, void (*)(void*), void*, int);

Improve error handling in threading_queue

There is a lack of error handling and reporting in these function. The functions should return consistent error codes. This could be implemented through an enum, however that may not be as effective for tq_start()

One possible solution is to modify tq_start() to take a pointer parameter for storing the number of successful thread creations. This would free the return value for the enum.

Improve thread yielding and cancellation

There is no reason why a thread should wait a certain amount of time if nothing else is running.

  • Use sched_yield() instead of usleep()
  • Remove the wait time information from threading_queue_startup_information
  • Add a cancellation point before calling fq_pop()

Memory leak in function_queue.c

In function_queue.c, attr is never destroyed. Possible fixes:

  • Keep track of number of queues
    • Initialize attr when number changes from 0 to 1
    • Destroy attr when number changes from 1 to 0
  • Initialize and destroy attributes every time a queue is initialized

Logic error in fq_init()

The logic that checks if malloc() succeeds in fq_init() is the opposite. It should be changed from:

ret = PT_EMALLOC
pml = pthread_mutex_destroy(&q->lock)

if(pml == 0) {

to

        ret = PT_EMALLOC
        pml = pthread_mutex_destroy(&q->lock)
} else {
        if(pml == 0) {

Additionally, PT_EPTMUNLOCK is the wrong error code, it should be PT_EPTMINIT.

Use a condition variable to block when the queue is empty

Use a condition variable to block to elimination repeated unnecessary checking in get_and_run(). Call pthread_cond_signal() from fq_push() and pthread_cond_wait() from fq_pop().

  • Remove locking from fq_is_empty() and fq_is_full()
  • Remove block parameter from fq_is_empty() and fq_is_full() (#24)
  • Make the lock non-recursive
  • Implement condition variable usage in fq_push() and fq_pop()

Allow function queue to resize

As it currently is, the function queue cannot resize with realloc() because the elements pointer could be dereferenced while it points to freed memory (before the pointer has been replaced with the new memory). A work-around could be to allocated with malloc() and manually copy the data from the original queue over, all while holding the lock.

Improve error handling

The error handling is a mess. The functions should return consistent error codes. This will be implemented through an enum. The enum value indicating the error status will be the return value the functions.

  • Create an enum for this purpose
  • Implement the error codes through the enum throughout the project (including #18)
    • Implement in function_queue
    • Implement in threading_queue
  • Create a function for looking up strings corresponding to error enums
    • Create tests for this function to ensure it works

Change the name tq::queue

The name is misleading. Perhaps tp::pool would be better.

Ideally this will happen after #27 for easier integration.

fq_peek() can block when it should not

The function fq_peek() can block when calling fq_is_empty() even if the block parameter is 0. The block parameter should be passed on to it instead of the constant 1.

fq_pop() can block when it should not

The function fq_pop() can block when calling fq_is_empty() even if the block parameter is 0. The block parameter should be passed on to it instead of the constant 1.

fq_push() can block when it should not

The function fq_push() can block when calling fq_is_full() even if the block parameter is 0. The block parameter should be passed on to it instead of the constant 1.

CI compiler update

Currently, the CI script specifically installs gcc-4.8. This may no longer be necessary. Determine if this can be removed.

Refactor error cleanup to use goto

It should look much cleaner and be less flaggy

  • fqinit()
  • fqdestroy()
  • fqpush()
  • fqpop()
  • fqpeek()
  • qtstrerror_r()
  • qtinit()
  • qstart_get_e() -- restructure returns; no goto

Refactor to allow for different types of structures for the function queue

This will facilitate the implementation of #16.

  • Implement a union to store the struct pointers in.
  • Implement an enum to determine which struct pointer to use and which features are available
  • Decide whether to use the enum or a structure of function pointers to determine which specific queue functions to call (will use function pointers)
    • Implement this decision

The solution must:

  • Allow users to interact with the queue in a way that does not require them to know what type is in use
  • Allow for easily adding and implementing more queue structures in the future

UB in get_and_run()

The function get_and_run() is of type void* (*) (struct function_queue*) but is called as void* (*)(void*). This results in undefined behavior according to the C Standard:

If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined.

Code needs to be cleaned up

There are some serious issues in the code that need to be cleaned up. For example, error handling and null-pointer checks.

  • General clean up
  • Error handling in function_queue (including #6) see #17
  • Error handling in threading_queue see #18
  • Debug assertions (maybe) see #20

What does this solve

Hey Brandon,

I just wanted to drop by and ask some existential questions.

Why does this project exist? What is the purpose of this? What problem does this solve?

Thanks,
Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.