Skip to content

Commit

Permalink
kernel rtab functional
Browse files Browse the repository at this point in the history
  • Loading branch information
nickbjohnson4224 committed Oct 15, 2011
1 parent 8c0d360 commit 0199a8f
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 213 deletions.
1 change: 0 additions & 1 deletion driver/tmpfs/main.c
Expand Up @@ -107,7 +107,6 @@ char *tmpfs_cons(struct robject *self, rp_t source, int argc, char **argv) {
return strdup("! arg");
}

// XXX SEC - does not check for write access
char *tmpfs_reset(struct robject *self, rp_t source, int argc, char **argv) {
uint8_t *file_data;
off_t *file_size;
Expand Down
2 changes: 2 additions & 0 deletions kernel/inc/ipc.h
Expand Up @@ -39,6 +39,8 @@
#define PORT_USER1 14
#define PORT_USER2 15

#define PORT_CLOSE 24

struct msg {
size_t count;
uint32_t *frame;
Expand Down
16 changes: 10 additions & 6 deletions kernel/inc/process.h
Expand Up @@ -30,14 +30,19 @@

/* process structure *******************************************************/

struct rtab {
uint64_t a;
uint64_t b;
};

struct process {

/* address space */
space_t space;

/* robject table */
uint32_t rtab_count;
uint64_t *rtab;
struct rtab *rtab;

/* various metadata */
uint64_t tick;
Expand Down Expand Up @@ -68,11 +73,10 @@ void process_switch(struct process *proc);
void process_freeze(struct process *proc);
void process_thaw (struct process *proc);

/* robject table operations ************************************************/
/* resource table operations ***********************************************/

void rtab_close(struct process *proc, uint64_t rp);
void rtab_grant(struct process *proc, uint64_t rp);
uint32_t rtab_count(uint64_t rp);
void rtab_free (struct process *proc);
void rtab_close(struct process *proc, uint64_t a, uint64_t b);
void rtab_open (struct process *proc, uint64_t a, uint64_t b);
void rtab_free (struct process *proc);

#endif/*KERNEL_PROCESS_H*/
1 change: 1 addition & 0 deletions kernel/inc/thread.h
Expand Up @@ -85,6 +85,7 @@ struct thread *thread_alloc (void);
void thread_free (struct thread *thread);
struct thread *thread_switch(struct thread *old, struct thread *new);
struct thread *thread_send (struct thread *image, pid_t target, portid_t port, struct msg *msg);
void thread_sendv (uint64_t target, uint64_t source, portid_t port);
struct thread *thread_freeze(struct thread *image);
struct thread *thread_thaw (struct thread *image);
struct thread *thread_exit (struct thread *image);
Expand Down
2 changes: 2 additions & 0 deletions kernel/process/process.c
Expand Up @@ -87,6 +87,8 @@ struct process *process_clone(struct process *parent, struct thread *active) {
child->parent = parent;
child->pid = pid;
child->rirq = IRQ_NULL;
child->rtab = NULL;
child->rtab_count = 0;

memclr(child->thread, sizeof(struct thread*) * 256);

Expand Down
200 changes: 36 additions & 164 deletions kernel/process/rtab.c
Expand Up @@ -15,173 +15,53 @@
*/

#include <process.h>
#include <thread.h>
#include <debug.h>
#include <space.h>
#include <types.h>

struct _refc_bucket {
struct _refc_bucket *next;
uint64_t rp;
uint32_t refc;
};

static uint32_t _refc_count = 8191; // large prime
static struct _refc_bucket *_refc_table[8191];

/*****************************************************************************
* _refc_hash
*
* Return the index of <rp> in the refc table.
*/

static uint32_t _refc_hash(uint64_t rp) {
uint32_t hash;

hash = rp & 0xFFFFFFFF;
hash = (hash << 16) + (hash << 6) - hash + (uint32_t) (rp >> 32);

return hash % _refc_count;
}

/*****************************************************************************
* _refc_get
*
* Return the reference count of the robject <rp>.
*/

static uint32_t _refc_get(uint64_t rp) {
struct _refc_bucket *bucket;

// find bucket
bucket = _refc_table[_refc_hash(rp)];
while (bucket) {
if (bucket->rp == rp) {
return bucket->refc;
}
bucket = bucket->next;
}

// entry not found
return 0;
}

/*****************************************************************************
* _refc_del
*
* Set the reference count of the robject <rp> to zero by removing it from
* the refc table.
*/

static void _refc_del(uint64_t rp) {
struct _refc_bucket *bucket;
struct _refc_bucket *temp;

bucket = _refc_table[_refc_hash(rp)];

// check if first entry is to be deleted
if (bucket->rp == rp) {
_refc_table[_refc_hash(rp)] = bucket->next;
heap_free(bucket, sizeof(struct _refc_bucket));
return;
}

// search bucket list for deletable entry
while (bucket->next) {
if (bucket->next->rp == rp) {
temp = bucket->next;
bucket->next = temp->next;
heap_free(temp, sizeof(struct _refc_bucket));
return;
}
bucket = bucket->next;
}

// entry not found
return;
}

/*****************************************************************************
* _refc_set
*
* Set the reference count of the robject <rp> to <refc>.
*/

static void _refc_set(uint64_t rp, uint32_t refc) {
struct _refc_bucket *bucket;
uint32_t hash = _refc_hash(rp);

if (refc == 0) {
// delete entry instead
_refc_del(rp);
return;
}

// find bucket
bucket = _refc_table[hash];
while (bucket) {
if (bucket->rp == rp) {
bucket->refc = refc;
}
bucket = bucket->next;
}

// entry not found; add new entry
bucket = heap_alloc(sizeof(struct _refc_bucket));
bucket->next = _refc_table[hash];
bucket->rp = rp;
bucket->refc = refc;
_refc_table[hash] = bucket;
}
#include <ipc.h>

/*****************************************************************************
* rtab_free
*
* Delete all robject table entries for the process <proc>. Reference counts
* for all entries are decremented.
* Delete all resource table entries for the process <proc>.
*/

void rtab_free(struct process *proc) {
uint32_t i;
uint32_t refc;

// traverse table
// close all entries
for (i = 0; i < proc->rtab_count; i++) {

if (proc->rtab[i]) {

// decrement reference count for entry
refc = _refc_get(proc->rtab[i]);
if (refc > 0) {
_refc_set(proc->rtab[i], refc - 1);
}
if (proc->rtab[i].a) {
rtab_close(proc, proc->rtab[i].a, proc->rtab[i].b);
}
}

if (proc->rtab) heap_free(proc->rtab, proc->rtab_count * sizeof(uint64_t));
if (proc->rtab) heap_free(proc->rtab, proc->rtab_count * sizeof(struct rtab));
proc->rtab = NULL;
proc->rtab_count = 0;
}

/*****************************************************************************
* rtab_close
*
* Delete the robject table entry for the robject <rp> in the process <proc>.
* The reference count for the robject <rp> is decremented.
* Delete the resource table entry for the connection <a>,<b> in the process
* <proc>. A notification is sent to <b> on port PORT_CLOSE if successful.
*/

void rtab_close(struct process *proc, uint64_t rp) {
uint32_t refc;
void rtab_close(struct process *proc, uint64_t a, uint64_t b) {
uint32_t i;

// find slot
for (i = 0; i < proc->rtab_count; i++) {

if (proc->rtab[i] == rp) {
if (proc->rtab[i].a == a || proc->rtab[i].b == b) {

// found slot
proc->rtab[i] = 0;
refc = _refc_get(rp);
if (refc > 0) {
_refc_set(rp, refc - 1);
}
thread_sendv(b, a, PORT_CLOSE);

proc->rtab[i].a = 0;
proc->rtab[i].b = 0;
return;
}
}
Expand All @@ -191,64 +71,56 @@ void rtab_close(struct process *proc, uint64_t rp) {
}

/*****************************************************************************
* rtab_grant
* rtab_open
*
* Add a robject table entry for the robject <rp> to the process <proc>. The
* reference count for the robject <rp> is incremented.
* Add a resource table entry for the connection <a>,<b> to the process
* <proc>.
*/

void rtab_grant(struct process *proc, uint64_t rp) {
void rtab_open(struct process *proc, uint64_t a, uint64_t b) {
uint32_t count;
uint64_t *temp;
uint64_t *temp2;
struct rtab *temp;
struct rtab *temp2;
uint32_t i;

// find empty slot for entry
for (i = 0; i < proc->rtab_count; i++) {

if (proc->rtab[i] == rp) {
// already contains this robject
if (proc->rtab[i].a == a || proc->rtab[i].b == b) {
// already contains this connection
return;
}

if (proc->rtab[i] == 0) {
if (proc->rtab[i].a == 0) {
// found suitable entry
proc->rtab[i] = rp;
_refc_set(rp, 1 + _refc_get(rp));
proc->rtab[i].a = a;
proc->rtab[i].b = b;
return;
}
}

// could not find slot; reallocate table
count = proc->rtab_count + 16;
temp = heap_alloc(count * sizeof(uint64_t));
temp = heap_alloc(count * sizeof(struct rtab));

// copy contents to new table
for (i = 0; i < proc->rtab_count; i++) {
temp[i] = proc->rtab[i];
for (i = 0; i < proc->rtab_count; i++) {
temp[i].a = proc->rtab[i].a;
temp[i].b = proc->rtab[i].b;
}

// clear remainder of table
for (; i < count; i++) {
temp[i] = 0;
temp[i].a = 0;
temp[i].b = 0;
}

// free old table
temp2 = proc->rtab;
proc->rtab = temp;
if (temp2) heap_free(temp2, proc->rtab_count * sizeof(uint64_t));
if (temp2) heap_free(temp2, proc->rtab_count * sizeof(struct rtab));
proc->rtab_count = count;

// add new entry
rtab_grant(proc, rp);
}

/*****************************************************************************
* rtab_count
*
* Returns the reference count of the given robject <rp>.
*/

uint32_t rtab_count(uint64_t rp) {
return _refc_get(rp);
rtab_open(proc, a, b);
}

0 comments on commit 0199a8f

Please sign in to comment.