<commit_before>#ifndef __WAIT_H__
#define __WAIT_H__

#include <sched.h>
#include <list.h>
#include <lib.h>
#include <os.h>

struct wait_queue
{
    struct thread *thread;
    struct list_head thread_list;
};

struct wait_queue_head
{
    /* TODO - lock required? */
    struct list_head thread_list;
};

#define DECLARE_WAIT_QUEUE_HEAD(name) \
   struct wait_queue_head name =     \
        { .thread_list = { &(name).thread_list, &(name).thread_list} }

#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
    .thread_list      = { &(name).thread_list, &(name).thread_list } }


#define DEFINE_WAIT(name)                               \
struct wait_queue name = {                              \
    .thread       = current,                            \
    .thread_list  = LIST_HEAD_INIT((name).thread_list), \
}


static inline void init_waitqueue_head(struct wait_queue_head *h)
{
  INIT_LIST_HEAD(&h->thread_list);
}

static inline void init_waitqueue_entry(struct wait_queue *q, struct thread *thread)
{
    q->thread = thread;
    INIT_LIST_HEAD(&q->thread_list);
}


static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue *q)
{
    if (list_empty(&q->thread_list))
        list_add(&q->thread_list, &h->thread_list);   
}

static inline void remove_wait_queue(struct wait_queue *q)
{
    list_del(&q->thread_list);
}

static inline void wake_up(struct wait_queue_head *head)
{
    struct list_head *tmp, *next;
    list_for_each_safe(tmp, next, &head->thread_list)
    {
         struct wait_queue *curr;
         curr = list_entry(tmp, struct wait_queue, thread_list);
         wake(curr->thread);
    }
}

#define add_waiter(w, wq) do {  \
    unsigned long flags;        \
    local_irq_save(flags);      \
    add_wait_queue(&wq, &w);    \
    block(current);             \
    local_irq_restore(flags);   \
} while (0)

#define remove_waiter(w) do {   \
    unsigned long flags;        \
    local_irq_save(flags);      \
    remove_wait_queue(&w);      \
    local_irq_restore(flags);   \
} while (0)

#define wait_event(wq, condition) do{             \
    unsigned long flags;                          \
    if(condition)                                 \
        break;                                    \
    DEFINE_WAIT(__wait);                          \
    for(;;)                                       \<commit_msg>[Mini-OS] Make wake_up callback-safe<commit_after>#ifndef __WAIT_H__
#define __WAIT_H__

#include <sched.h>
#include <list.h>
#include <lib.h>
#include <os.h>

struct wait_queue
{
    struct thread *thread;
    struct list_head thread_list;
};

struct wait_queue_head
{
    /* TODO - lock required? */
    struct list_head thread_list;
};

#define DECLARE_WAIT_QUEUE_HEAD(name) \
   struct wait_queue_head name =     \
        { .thread_list = { &(name).thread_list, &(name).thread_list} }

#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
    .thread_list      = { &(name).thread_list, &(name).thread_list } }


#define DEFINE_WAIT(name)                               \
struct wait_queue name = {                              \
    .thread       = current,                            \
    .thread_list  = LIST_HEAD_INIT((name).thread_list), \
}


static inline void init_waitqueue_head(struct wait_queue_head *h)
{
  INIT_LIST_HEAD(&h->thread_list);
}

static inline void init_waitqueue_entry(struct wait_queue *q, struct thread *thread)
{
    q->thread = thread;
    INIT_LIST_HEAD(&q->thread_list);
}


static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue *q)
{
    if (list_empty(&q->thread_list))
        list_add(&q->thread_list, &h->thread_list);   
}

static inline void remove_wait_queue(struct wait_queue *q)
{
    list_del(&q->thread_list);
}

static inline void wake_up(struct wait_queue_head *head)
{
    unsigned long flags;
    struct list_head *tmp, *next;
    local_irq_save(flags);
    list_for_each_safe(tmp, next, &head->thread_list)
    {
         struct wait_queue *curr;
         curr = list_entry(tmp, struct wait_queue, thread_list);
         wake(curr->thread);
    }
    local_irq_restore(flags);
}

#define add_waiter(w, wq) do {  \
    unsigned long flags;        \
    local_irq_save(flags);      \
    add_wait_queue(&wq, &w);    \
    block(current);             \
    local_irq_restore(flags);   \
} while (0)

#define remove_waiter(w) do {   \
    unsigned long flags;        \
    local_irq_save(flags);      \
    remove_wait_queue(&w);      \
    local_irq_restore(flags);   \
} while (0)

#define wait_event(wq, condition) do{             \
    unsigned long flags;                          \
    if(condition)                                 \
        break;                                    \
    DEFINE_WAIT(__wait);                          \
    for(;;)                                       \
{'fraction_non_alphanumeric': 0.1117948717948718, 'fraction_numerical': 0.0008205128205128205, 'mean_word_length': 2.030453697949037, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4351537', 'n_tokens_mistral': 1585, 'n_tokens_neox': 1580, 'n_words': 302}