[NSWI004] Thread queue hurts
Vojtech Horky
horky at d3s.mff.cuni.cz
Fri Dec 11 07:07:08 CET 2020
Hello.
Dne 10. 12. 20 v 12:18 Jan Kytka napsal(a):
> Hello,
>
> our team got a comment about ugly thread queue implementation, which was
> implemented using a generic list_t macro that takes: type of list item,
> the link member and name
> of the new specialised struct, and expands to a new specialised struct
> containing list_t
> and all the methods used to work with the new struct.
Ooops, sorry about an unclear comment. It was supposed to refer to the
mixing of camelCase and snake_case names and should have been merged
with the previous comment about formatting ;-).
>
> I understand that this is not the most beautiful thing under the sun :-)
>
> But anyhow, I couldn't figure out how to make the thread queue a
> first-class citizen
> while at the same time make it reusable by both the scheduler and the
> mutex, since
> they each use different link_t in the thread_t structure.
My point was rather that the name suggests it is a queue implementation
but regarding types, it is still just list_t and also the user has to
use struct_container_of macro. I guess it comes from the fact that you
do not want to expose the whole list_generic in the mutex.h header but
it just seems confusing to me.
As a side-note: it would actually be possible to use the same link for
both scheduler and mutexes (either the thread is ready or is blocked).
To me, the following is easier to use, provides pretty good type-safety
and offers little space for misuse. And it can be used by both mutexes
and semaphores, and eventually by also the disk driver, for example.
typedef struct {
list_t queue;
} thread_queue_t;
struct thread {
...
link_t queue_link;
...
}
typedef struct {
thread_queue_t waiting_threads;
...
} mutex_t;
void thread_queue_enqeueu(thread_queue_t *tq, thread_t *t) {
list_append(&tq->list, &t->link);
}
thread_t *thread_queue_dequeue(thread_queue_t *tq) { ... }
I would even go one step further and add functions that block the
current thread after adding it to the queue and waking-up the first
queue as top-level operations as that is the typical use.
But this is also not perfect. Your list_generic avoid some code
duplication that is needed here, on the other hand here we do not add an
extra member just to keep the type information etc. etc.
As for many other comments to your solutions - if we believe that
another approach balances the ease of use, readability, maintainability
etc. better, we try to mention it. It is up to you whether you want to
change your code or not. You know it better than we do and can decide
whether the change is worth it.
I hope this explains things a bit better, I am sorry if the intent of
the comment was not clear from the grading file.
Cheers,
- VH
More information about the NSWI004
mailing list