#ifndef __DEV_NTSYNCVAR_H__
#define __DEV_NTSYNCVAR_H__
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <dev/ntsync/ntsync.h>
enum ntsync_obj_type {
NTSYNC_OBJ_SEM,
NTSYNC_OBJ_MUTEX,
NTSYNC_OBJ_EVENT,
};
struct ntsync_wait_state;
struct ntsync_obj_waiter {
struct ntsync_wait_state *state;
TAILQ_ENTRY(ntsync_obj_waiter) link;
};
struct ntsync_obj {
enum ntsync_obj_type type;
struct ntsync_priv *owner;
TAILQ_HEAD(, ntsync_obj_waiter) waiters;
bool (*is_signaled)(struct ntsync_obj *,
struct ntsync_wait_state *state, int index);
void (*consume)(struct ntsync_obj *, struct ntsync_wait_state *,
int index);
bool (*prepare)(struct ntsync_obj *, struct ntsync_wait_state *state,
int index, bool *stop);
void (*commit)(struct ntsync_obj *, struct ntsync_wait_state *state,
int index);
void (*post_commit)(struct ntsync_obj *,
struct ntsync_wait_state *state, int index);
};
struct ntsync_obj_sem {
struct ntsync_obj obj;
struct ntsync_sem_args a;
struct ntsync_sem_args a1;
};
#define OBJ_TO_SEM(obj) __containerof(obj, struct ntsync_obj_sem, obj)
struct ntsync_obj_mutex {
struct ntsync_obj obj;
struct ntsync_mutex_args a;
struct ntsync_mutex_args a1;
bool abandoned;
};
#define OBJ_TO_MUTEX(obj) __containerof(obj, struct ntsync_obj_mutex, obj)
struct ntsync_obj_event {
struct ntsync_obj obj;
struct ntsync_event_args a;
struct ntsync_event_args a1;
bool pulse;
};
#define OBJ_TO_EVENT(obj) __containerof(obj, struct ntsync_obj_event, obj)
struct ntsync_wait_state {
struct ntsync_wait_args *nwa;
struct ntsync_priv *owner;
struct ntsync_obj_waiter waiters[NTSYNC_MAX_WAIT_COUNT + 1];
int fds[NTSYNC_MAX_WAIT_COUNT];
struct file *fps[NTSYNC_MAX_WAIT_COUNT];
struct file *fp_alert;
int obj_count;
struct ntsync_obj *objs[NTSYNC_MAX_WAIT_COUNT + 1];
struct ntsync_obj_event *alert_event;
sbintime_t sb;
sbintime_t prec;
int error;
int index;
bool any;
bool all;
bool ready;
};
struct ntsync_priv {
struct mtx lock;
unsigned objs_cnt;
bool closed;
};
#define NTSYNC_PRIV_LOCK(priv) mtx_lock(&priv->lock)
#define NTSYNC_PRIV_UNLOCK(priv) mtx_unlock(&priv->lock)
#define NTSYNC_PRIV_ASSERT(priv) mtx_assert(&priv->lock, MA_OWNED)
extern struct cdevsw ntsync_cdevsw;
struct file;
struct thread;
int ntsync_sem_release(struct thread *td, struct file *fp, uint32_t *val);
int ntsync_sem_read(struct thread *td, struct file *fp,
struct ntsync_sem_args *a);
int ntsync_mutex_unlock(struct thread *td, struct file *fp,
struct ntsync_mutex_args *a);
int ntsync_mutex_kill(struct thread *td, struct file *fp, uint32_t val);
int ntsync_mutex_read(struct thread *td, struct file *fp,
struct ntsync_mutex_args *a, bool *doco);
int ntsync_event_set(struct thread *td, struct file *fp, uint32_t *val);
int ntsync_event_reset(struct thread *td, struct file *fp, uint32_t *val);
int ntsync_event_pulse(struct thread *td, struct file *fp, uint32_t *val);
int ntsync_event_read(struct thread *td, struct file *fp,
struct ntsync_event_args *a);
#endif