Commit 7847ab98 authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

lcd: Remove redundant files

Remove leftover files during merge that are not needed/compiled anymore.
parent ef639a11
/* Author: Anton Burtsev
* Copyright: University of Utah */
#ifndef __LCD_CAP_H__
#define __LCD_CAP_H__
#include <linux/types.h>
#include <linux/spinlock.h>
#include "cap-cache.h"
#include <uapi/linux/lcd-cap.h>
#define LCD_MAX_CAPS 32
#define CAP_IDENTIFIER_BITS 2
#define TABLE_IDENTIFIER_BITS 1
// should always be 2^CAP_IDENTIFIER_BITS
#define MAX_CAP_SLOTS 4
// should always be 2^TABLE_IDENTIFIER_BITS
#define MAX_TABLE_ID_SLOTS 2
// should always be 2^CAP_IDENTIFIER_BITS + 2^TABLE_IDENTIFIER_BITS
#define MAX_SLOTS_PER_TABLE 6
struct cdt_root_node;
struct cnode;
struct cspace;
extern struct cdt_root_node * get_cdt_root(void);
extern void free_cdt_root(struct cdt_root_node *cdt_node);
enum lcd_cap_type
{
LCD_CAP_TYPE_INVALID,
LCD_CAP_TYPE_FREE,
LCD_CAP_TYPE_SYNC_EP,
LCD_CAP_TYPE_CNODE
};
enum allocation_state {
ALLOCATION_INVALID,
ALLOCATION_VALID,
ALLOCATION_MARKED_FOR_DELETE,
ALLOCATION_REMOVED
};
struct cdt_root_node {
spinlock_t lock;
struct cnode *cnode;
unsigned long node_count;
enum allocation_state state;
};
struct cnode {
enum lcd_cap_type type;
void *object;
spinlock_t lock;
struct cdt_root_node *cdt_root;
struct cnode *parent, *child, *prev, *next;
capability_t cap;
struct cspace *cspace;
};
struct cnode_table {
struct cnode cnode[MAX_SLOTS_PER_TABLE];
uint8_t table_level;
};
struct cspace {
spinlock_t lock;
enum allocation_state state;
struct cnode_table *cnode_table;
struct kmem_cache *cnode_table_cache;
struct cap_cache cap_cache;
};
bool _get_level_bits(int table_level, capability_t cap, capability_t *levelId);
bool _lcd_delete_node (struct cnode *cnode);
int _lcd_delete_table(struct cspace *cspace, struct cnode_table *table);
int lcd_cap_init_cspace(struct cspace *cspace);
struct cnode *lcd_cnode_lookup(struct cspace *cspace, capability_t cap, bool alloc);
int lcd_cap_insert(struct cspace *cspace, capability_t cap,
void *object, enum lcd_cap_type type);
void lcd_cap_delete(struct cspace *cspace, capability_t cap);
int lcd_cap_grant(struct cspace *cspacesrc, capability_t capsrc, struct cspace *cspacedst, capability_t capdst);
int lcd_cap_revoke(struct cspace *cspace, capability_t cap);
int lcd_cap_destroy_cspace(struct cspace *cspace);
#endif
#ifndef HOST_IPC_H
#define HOST_IPC_H
#include <uapi/linux/lcd-ipc.h>
#include <lcd/cap.h>
struct sync_ipc {
struct list_head senders;
struct list_head receivers;
spinlock_t lock;
};
/* Per thread kernel stack unified on a single page. */
union utcb_union {
struct utcb utcb;
char kstack[PAGE_SIZE];
};
struct sync_ipc * alloc_sync_ipc(void);
int lcd_ipc_init(void);
int lcd_ipc_exit(void);
#endif
/*
* Author: Charles Jacobsen <charlesj@cs.utah.edu>
* Copyright: University of Utah
*/
#ifndef LCD_LCD_H
#define LCD_LCD_H
#define LCD_NUM_REGS 8
#define LCD_NUM_OUT_CAP_REGS 8
#define LCD_NUM_IN_CAP_REGS LCD_NUM_OUT_CAP_REGS
#define LCD_NUM_BOOT_CPTRS 8
struct cspace;
typedef u64 cptr_t;
struct lcd {
/*
* Not accessible in lcd
*/
struct task_struct *parent;
u64 badge;
struct cspace *cspace;
struct list_head senders;
struct list_head receivers;
int making_call;
/*
* Accessible in lcd
*/
struct {
cptr_t boot_cptrs[LCD_NUM_BOOT_CPTRS];
u64 regs[LCD_NUM_REGS];
cptr_t out_cap_regs[LCD_NUM_OUT_CAP_REGS];
cptr_t in_cap_regs[LCD_NUM_IN_CAP_REGS];
u8 max_valid_reg_idx;
u8 max_valid_out_cap_reg_idx;
u8 max_valid_in_cap_reg_idx;
cptr_t call_endpoint_cap;
cptr_t reply_endpoint_cap;
} utcb;
};
#endif /* LCD_LCD_H */
......@@ -184,8 +184,6 @@ KASAN_SANITIZE_stackdepot.o := n
libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
fdt_empty_tree.o
obj-$(CONFIG_LCD_ASYNC) += thc/
$(foreach file, $(libfdt_files), \
$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
lib-$(CONFIG_LIBFDT) += $(libfdt_files)
......
#
# LCD ASYNC
#
config LAZY_THC
bool "CONFIG LAZY THC"
default y
---help---
LAZY ASYNC Implementation
obj-$(CONFIG_LAZY_THC) += async.o
async-y := main.o thc.o thcsync.o
/*
* main.c
*
* Authors: Anton Burtsev <aburtsev@flux.utah.edu>
* Muktesh Khole <muktesh.khole@utah.edu>
* Copyright: University of Utah
*/
#include <linux/init.h>
#include <linux/module.h>
#include <lcd-domains/thc.h>
#include <lcd-domains/thcinternal.h>
#include <lcd-domains/thcsync.h>
void foo1(void);
void foo2(void);
bool testFlag = false;
void foo1(void) {
printk(KERN_ERR "lcd async entering foo1");
while (testFlag == false) {
printk(KERN_ERR "lcd async yielding to foo2");
THCYield();
}
printk(KERN_ERR "lcd async foo1 complete");
}
void foo2(void) {
printk(KERN_ERR "lcd async entering foo2");
testFlag = true;
}
static int __init api_init(void)
{
DO_FINISH(ASYNC(foo1();foo2();););
printk(KERN_ERR "lcd async entering module");
return 0;
}
static void __exit api_exit(void)
{
printk(KERN_ERR "lcd async exiting module");
return;
}
module_init(api_init);
module_exit(api_exit);
This diff is collapsed.
//
// Synchronization primitives
//
//#include <stdlib.h>
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
#include <lcd-domains/thc.h>
#define NOT_REACHED assert(0 && "Not reached")
#define DEBUGPRINTF debug_printf
#define DEBUG_SYNC(XX)
//#define DEBUG_SYNC(XX) do{ XX; } while (0)
#define DEBUG_SYNC_PREFIX " sync: "
//......................................................................
//
// Latches
void thc_latch_init(struct thc_latch *l) {
l->c = 0;
}
//......................................................................
//
// Semaphores
void thc_sem_init(thc_sem_t *s, int val) {
thc_latch_init(&s->l);
s->val = val;
s->q = NULL;
}
static void thc_sem_p0(void *s) {
thc_sem_t *sem = (thc_sem_t*)s;
thc_latch_release(&sem->l);
}
void thc_sem_p(thc_sem_t *s) {
thc_latch_acquire(&s->l);
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p(%p) %d\n", s, s->val));
if (s->val == 0) {
struct thc_waiter w;
w.next = s->q;
s->q = &w;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p sleeping %p\n", &w));
THCSuspendThen(&w.waiter, thc_sem_p0, (void*)s); // Sleep ......
thc_latch_acquire(&s->l);
} else {
s->val --;
}
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p(%p) done\n", s));
thc_latch_release(&s->l);
}
// Information passed to a semaphore wait cancel function: we need a
// reference to the semaphore (so we can walk down its list to remove
// the waiter) and a reference to the waiter itself (to identify the
// item to remove, and to identify the AWE to resume).
//
// NB: we distinguish woken/canceled by an explicit flag in this
// structure to avoid races between (i) getting the lock in the
// cancelation action, and (ii) being woken from a V operation. We
// cannot just look at whether or not the cancelation action ran.
struct thc_sem_cancel_info {
struct thc_waiter *waiter_info;
thc_sem_t *sem;
int was_canceled;
};
static void thc_sem_p_x_cancel_fn(void *c) {
struct thc_sem_cancel_info *cinf = (struct thc_sem_cancel_info *)c;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Woken cinf=%p\n", cinf));
// When we start waiting for the latch, we know that the thread
// that invoked thc_sem_p_x has reached the end of a cancel block
// and is processing cancel items. We know that the cancel
// item for the thc_sem_p_x has not been removed.
thc_latch_acquire(&cinf->sem->l);
// When we finish waiting for the latch, it is possible that
// another thread has executed a V operation that has unblocked
// the thc_sem_p_x.
if (cinf->waiter_info->waiter == NULL) {
// Cancelation lost wake/cancel race: leave was_canceled false,
// leave waiter on the thread's run-queue, release the lock and
// return.
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Cancelation lost wake/cancel race\n"));
} else {
// Cancelation won any wake/cancel race: remove the waiter so
// that it cannot receive a subsequent V.
struct thc_waiter **qptr = &(cinf->sem->q);
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Looking for wait-queue entry %p\n", cinf->waiter_info));
cinf -> was_canceled = 1;
while ((*qptr) != NULL && *qptr != cinf->waiter_info) {
qptr = &((*qptr)->next);
}
//assert((*qptr) != NULL && "Could not find waiter entry on cancel");
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Removed wait-queue entry (now %p -> %p)\n", qptr, (*qptr)->next));
*qptr = (*qptr)->next;
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Waking p_x operation\n"));
THCSchedule(cinf->waiter_info->waiter);
}
thc_latch_release(&cinf->sem->l);
}
errval_t thc_sem_p_x(thc_sem_t *s) {
int canceled = 0;
// Return THC_CANCELED if already requested
if (THCIsCancelRequested()) {
return THC_CANCELED;
}
thc_latch_acquire(&s->l);
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p_x(%p) %d\n", s, s->val));
if (s->val == 0) {
struct thc_sem_cancel_info cinf;
cancel_item_t ci;
struct thc_waiter w;
cinf.waiter_info = &w;
cinf.sem = s;
cinf.was_canceled = 0;
w.next = s->q;
s->q = &w;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p_x sleeping %p\n", &w));
THCAddCancelItem(&ci, &thc_sem_p_x_cancel_fn, (void*)&cinf);
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Adding cancel item\n"));
THCSuspendThen(&w.waiter, thc_sem_p0, (void*)s); // Sleep ......
canceled = cinf.was_canceled;
if (!canceled) {
if (!THCCancelItemRan(&ci)) {
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Removing cancel item\n"));
THCRemoveCancelItem(&ci);
}
}
thc_latch_acquire(&s->l);
} else {
s->val --;
}
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_p_x(%p) done\n", s));
thc_latch_release(&s->l);
return canceled ? THC_CANCELED : SYS_ERR_OK;
}
void thc_sem_v(thc_sem_t *s) {
thc_latch_acquire(&s->l);
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_v(%p)\n", s));
if (s->q != NULL) {
awe_t *to_wake;
struct thc_waiter *w = s->q;
s->q = w->next;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_sem_v waking %p\n", w));
// NB: unlink the waiter structure before scheduling: they may
// run immediately on a concurrent thread, and de-allcoate the
// waiter structure.
to_wake = w->waiter;
// NULL out waiter; signals to the cancelation function
// that they lost a wake-up/cancel race
w->waiter = NULL;
THCSchedule(to_wake);
} else {
s->val ++;
}
thc_latch_release(&s->l);
}
//......................................................................
//
// Locks
#ifndef MUTEX_IS_LATCH
void thc_lock_init(thc_lock_t *l) {
thc_sem_init(&(l->sem), 1);
}
void thc_lock_acquire(thc_lock_t *l) {
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_lock_acquire %p\n", l));
thc_sem_p(&(l->sem));
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_lock_acquire done\n"));
}
void thc_lock_release(thc_lock_t *l) {
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_lock_release %p\n", l));
thc_sem_v(&(l->sem));
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_lock_release done\n"));
}
#endif
//......................................................................
//
// Condition variables
void thc_condvar_init(thc_condvar_t *cv) {
thc_latch_init(&cv->l);
cv->q = NULL;
}
typedef struct {
thc_condvar_t *cv;
thc_lock_t *lock;
} thc_condvar_wait0_info_t;
static void thc_condvar_wait0(void *v) {
thc_condvar_wait0_info_t *info = (thc_condvar_wait0_info_t *) v;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait releasing lock %p\n", info->lock));
thc_latch_release(&info->cv->l);
thc_lock_release(info->lock);
}
void thc_condvar_wait(thc_condvar_t *cv, thc_lock_t *lock) {
struct thc_waiter w;
thc_condvar_wait0_info_t info;
thc_latch_acquire(&cv->l);
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait(%p,%p)\n", cv, lock));
w.next = cv->q;
cv->q = &w;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait sleeping %p\n", &w));
info.cv = cv;
info.lock = lock;
THCSuspendThen(&w.waiter, thc_condvar_wait0, (void*)&info); // Sleep ......
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait retaking lock %p\n", lock));
thc_latch_acquire(&cv->l);
thc_lock_acquire(lock);
thc_latch_release(&cv->l);
}
// Information passed to a condvar wait cancel function: we need a
// reference to the condvar (so we can walk down its list to remove
// the waiter) and a reference to the waiter itself (to identify the
// item to remove, and to identify the AWE to resume).
//
// NB: we distinguish woken/canceled by an explicit flag in this
// structure to avoid races between (i) getting the lock in the
// cancelation action, and (ii) being woken from a notify operation. We
// cannot just look at whether or not the cancelation action ran.
struct thc_cv_cancel_info {
struct thc_waiter *waiter_info;
thc_condvar_t *cv;
int was_canceled;
};
static void thc_condvar_wait_x_cancel_fn(void *c) {
struct thc_cv_cancel_info *cinf = (struct thc_cv_cancel_info *)c;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Woken cinf=%p\n", cinf));
thc_latch_acquire(&cinf->cv->l);
if (cinf->waiter_info->waiter == NULL) {
// Cancelation lost wake/cancel race: leave was_canceled false,
// leave waiter on the thread's run-queue, release the lock and
// return.
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Cancelation lost wake/cancel race\n"));
} else {
struct thc_waiter **qptr = &(cinf->cv->q);
// Cancelation won any wake/cancel race: remove the waiter so
// that it cannot receive a subsequent notify.
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Looking for wait-queue entry %p\n", cinf->waiter_info));
cinf -> was_canceled = 1;
while ((*qptr) != NULL && *qptr != cinf->waiter_info) {
qptr = &((*qptr)->next);
}
//assert((*qptr) != NULL && "Could not find waiter entry on cancel");
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Removed wait-queue entry (now %p -> %p)\n", qptr, (*qptr)->next));
*qptr = (*qptr)->next;
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Waking condvar_wait_x operation\n"));
THCSchedule(cinf->waiter_info->waiter);
}
thc_latch_release(&cinf->cv->l);
}
errval_t thc_condvar_wait_x(thc_condvar_t *cv, thc_lock_t *lock) {
int canceled = 0;
struct thc_cv_cancel_info cinf;
cancel_item_t ci;
struct thc_waiter w;
thc_condvar_wait0_info_t info;
// Return THC_CANCELED if already requested
if (THCIsCancelRequested()) {
return THC_CANCELED;
}
thc_latch_acquire(&cv->l);
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait(%p,%p)\n", cv, lock));
cinf.waiter_info = &w;
cinf.cv = cv;
cinf.was_canceled = 0;
w.next = cv->q;
cv->q = &w;
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait sleeping %p\n", &w));
info.cv = cv;
info.lock = lock;
THCAddCancelItem(&ci, &thc_condvar_wait_x_cancel_fn, (void*)&cinf);
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Adding cancel item\n"));
THCSuspendThen(&w.waiter, thc_condvar_wait0, (void*)&info); // Sleep ......
canceled = cinf.was_canceled;
if (!canceled) {
if (!THCCancelItemRan(&ci)) {
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "Removing cancel item\n"));
THCRemoveCancelItem(&ci);
}
}
//DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_wait retaking lock %p\n", lock));
thc_latch_acquire(&cv->l);
thc_lock_acquire(lock);
thc_latch_release(&cv->l);
return canceled ? THC_CANCELED : SYS_ERR_OK;
}
void thc_condvar_signal(thc_condvar_t *cv) {
thc_latch_acquire(&cv->l);
if (cv->q != NULL) {
struct thc_waiter *w = cv->q;
awe_t *to_wake = w->waiter;
// NULL out waiter; signals to the cancelation function
// that they lost a wake-up/cancel race
w->waiter = NULL;
cv->q = w->next;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_signal waking %p\n", w));
THCSchedule(to_wake);
}
thc_latch_release(&cv->l);
}
void thc_condvar_broadcast(thc_condvar_t *cv) {
struct thc_waiter *w;
thc_latch_acquire(&cv->l);
w = cv->q;
while (w != NULL) {
awe_t *to_wake = w->waiter;
// NULL out waiter; signals to the cancelation function
// that they lost a wake-up/cancel race
w->waiter = NULL;
DEBUG_SYNC(DEBUGPRINTF(DEBUG_SYNC_PREFIX "thc_condvar_signal waking %p\n", w));
THCSchedule(to_wake);
w=w->next;
}
cv->q = NULL;
thc_latch_release(&cv->l);
}
//......................................................................
//
// FIFO queue
void thc_queue_init(thc_queue_t *tq) {
thc_lock_init(&tq->l);
thc_condvar_init(&tq->cv);
tq->start.bailed = tq->end.bailed = 0;
tq->start.served = tq->end.served = 0;
tq->start.prev = tq->end.next = NULL;
tq->start.next = &(tq->end);
tq->end.prev = &(tq->start);
}
void thc_queue_enter(thc_queue_t *tq,
thc_queue_entry_t *te) {
thc_lock_acquire(&tq->l);
te->bailed = 0;
te->served = 0;
te->prev = tq->end.prev;
te->next = &(tq->end);
tq->end.prev->next = te;
tq->end.prev = te;
thc_lock_release(&tq->l);
}
void thc_queue_await_turn(thc_queue_t *tq,
thc_queue_entry_t *te) {
thc_lock_acquire(&tq->l);
while (tq->start.next != te) {
thc_condvar_wait(&tq->cv, &tq->l);
}
te->served = 1;
thc_lock_release(<