// Main public header file for our user-land support library,
// whose code lives in the lib directory.
// This library is roughly our OS's version of a standard C library,
// and is intended to be linked into all user-mode applications
// (NOT the kernel or boot loader).

#pragma once

#ifndef __ASSEMBLER__

#include <parlib/common.h>
#include <parlib/vcore.h>
#include <parlib/core_set.h>
#include <ros/memlayout.h>
#include <ros/syscall.h>
#include <ros/procinfo.h>
#include <ros/procdata.h>
#include <signal.h>
#include <stdint.h>
#include <errno.h>
#include <ros/fdtap.h>

__BEGIN_DECLS

enum {
	PG_RDONLY = 4,
	PG_RDWR   = 6,
};

extern const char *const __syscall_tbl[];
extern int __syscall_tbl_sz;

int sys_null(void);
size_t sys_getpcoreid(void);
int sys_proc_destroy(int pid, int exitcode);
void sys_yield(bool being_nice);
int sys_proc_create(const char *path, size_t path_l, char *const argv[],
                    char *const envp[], int flags);
int sys_proc_run(int pid);
ssize_t sys_shared_page_alloc(void **addr, pid_t p2, int p1_flags,
			      int p2_flags);
ssize_t sys_shared_page_free(void *addr, pid_t p2);
void sys_reboot();
void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
	       size_t offset);
int sys_provision(int pid, unsigned int res_type, long res_val);
int sys_notify(int pid, unsigned int ev_type, struct event_msg *u_msg);
int sys_self_notify(uint32_t vcoreid, unsigned int ev_type,
		    struct event_msg *u_msg, bool priv);
int sys_send_event(struct event_queue *ev_q, struct event_msg *ev_msg,
		   uint32_t vcoreid);
int sys_halt_core(unsigned long usec);
void *sys_init_arsc(void);
int sys_block(unsigned long usec);
int sys_change_vcore(uint32_t vcoreid, bool enable_my_notif);
int sys_change_to_m(void);
int sys_poke_ksched(int pid, unsigned int res_type);
int sys_abort_sysc(struct syscall *sysc);
int sys_abort_sysc_fd(int fd);
int sys_tap_fds(struct fd_tap_req *tap_reqs, size_t nr_reqs);

void syscall_async(struct syscall *sysc, unsigned long num, ...);
void syscall_async_evq(struct syscall *sysc, struct event_queue *evq, unsigned
		       long num, ...);

/* Control variables */
extern bool parlib_wants_to_be_mcp;	/* instructs the 2LS to be an MCP */
extern bool parlib_never_yield;	/* instructs the 2LS to not yield vcores */
extern bool parlib_never_vc_request;/* 2LS: do not request vcores */

/* Process Management */
pid_t create_child(const char *exe, int argc, char *const argv[],
                   char *const envp[]);
pid_t create_child_with_stdfds(const char *exe, int argc, char *const argv[],
                               char *const envp[]);
int provision_core_set(pid_t pid, const struct core_set *cores);

/* Once */
typedef struct {
	bool ran_once;
	bool is_running;
} parlib_once_t;

#define PARLIB_ONCE_INIT {FALSE, FALSE}

/* Makes sure func is run exactly once.  Can handle concurrent callers, and
 * other callers spin til the func is complete. */
static inline void parlib_run_once(parlib_once_t *once_ctl,
                                   void (*init_fn)(void *), void *arg)
{
	if (!once_ctl->ran_once) {
		/* fetch and set TRUE, without a header or test_and_set
		 * weirdness */
		if (!__sync_fetch_and_or(&once_ctl->is_running, TRUE)) {
			/* we won the race and get to run the func */
			init_fn(arg);
			/* don't let the ran_once write pass previous writes */
			wmb();
			once_ctl->ran_once = TRUE;
		} else {
			/* someone else won */
			while (!once_ctl->ran_once)
				cpu_relax_any();
		}
	}
}

/* Unprotected, single-threaded version, makes sure func is run exactly once */
static inline void parlib_run_once_racy(parlib_once_t *once_ctl,
                                        void (*init_fn)(void *), void *arg)
{
	if (!once_ctl->ran_once) {
		init_fn(arg);
		once_ctl->ran_once = TRUE;
	}
}

static inline void parlib_set_ran_once(parlib_once_t *once_ctl)
{
	once_ctl->ran_once = TRUE;
}

/* Aborts with 'retcmd' if this function has already been called.  Compared to
 * run_once, this is put at the top of a function that can be called from
 * multiple sources but should only execute once. */
#define parlib_init_once_racy(retcmd)                                          \
do {                                                                           \
	static bool initialized = FALSE;                                       \
	if (initialized) {                                                     \
		retcmd;                                                        \
	}                                                                      \
	initialized = TRUE;                                                    \
} while (0)

__END_DECLS

#endif	// !ASSEMBLER
