Add locked ring buffer
This commit is contained in:
parent
c3b4d65a36
commit
d1994d44a3
@ -1,6 +1,7 @@
|
||||
#include "alloc.h"
|
||||
#include "klibc.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "synchro.h"
|
||||
|
||||
struct ringbuffer_instance_t {
|
||||
int32_t wr_pos;
|
||||
@ -12,12 +13,18 @@ struct ringbuffer_instance_t {
|
||||
|
||||
ringbuffer_t ringbufferCreate(uint32_t capacity)
|
||||
{
|
||||
ringbuffer_t inst = zalloc(1* sizeof(struct ringbuffer_instance_t));
|
||||
inst->data = zalloc(capacity * sizeof(uint8_t));
|
||||
inst->capacity = capacity;
|
||||
inst->wr_pos = 0;
|
||||
inst->rd_pos = 0;
|
||||
inst->full = capacity == 0;
|
||||
ringbuffer_t inst = zalloc(1 * sizeof(struct ringbuffer_instance_t));
|
||||
if (inst == NULL)
|
||||
return NULL;
|
||||
inst->data = zalloc(capacity * sizeof(uint8_t));
|
||||
if (inst->data == NULL) {
|
||||
free(inst);
|
||||
return NULL;
|
||||
}
|
||||
inst->capacity = capacity;
|
||||
inst->wr_pos = 0;
|
||||
inst->rd_pos = 0;
|
||||
inst->full = capacity == 0;
|
||||
|
||||
return inst;
|
||||
}
|
||||
@ -35,19 +42,19 @@ uint32_t ringbufferUsed(ringbuffer_t instance)
|
||||
return (instance->wr_pos - instance->rd_pos) % instance->capacity;
|
||||
}
|
||||
|
||||
bool_t ringbufferEmpty(ringbuffer_t instance)
|
||||
bool_t ringbufferIsEmpty(ringbuffer_t instance)
|
||||
{
|
||||
return (!instance->full && (instance->wr_pos == instance->rd_pos));
|
||||
}
|
||||
|
||||
bool_t ringbufferFull(ringbuffer_t instance)
|
||||
bool_t ringbufferIsFull(ringbuffer_t instance)
|
||||
{
|
||||
return instance->full;
|
||||
}
|
||||
|
||||
bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item)
|
||||
{
|
||||
if (ringbufferFull(instance))
|
||||
if (ringbufferIsFull(instance))
|
||||
return FALSE;
|
||||
|
||||
instance->data[instance->wr_pos] = item;
|
||||
@ -60,7 +67,7 @@ bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item)
|
||||
|
||||
bool_t ringbufferDequeue(ringbuffer_t instance, uint8_t *item)
|
||||
{
|
||||
if (ringbufferEmpty(instance))
|
||||
if (ringbufferIsEmpty(instance))
|
||||
return FALSE;
|
||||
|
||||
instance->full = FALSE;
|
||||
@ -85,3 +92,93 @@ void ringbufferDebug(ringbuffer_t instance)
|
||||
printf("%d/%d %d %d %s\n", ringbufferUsed(instance), ringbufferCapacity(instance),
|
||||
instance->wr_pos, instance->rd_pos, instance->full ? "(full)" : "");
|
||||
}
|
||||
|
||||
struct locked_ringbuffer_instance_t {
|
||||
struct ringbuffer_instance_t *ring;
|
||||
struct mutex mut;
|
||||
};
|
||||
|
||||
locked_ringbuffer_t lringbufferCreate(uint32_t capacity)
|
||||
{
|
||||
locked_ringbuffer_t inst = zalloc(sizeof(locked_ringbuffer_t));
|
||||
if (inst == NULL)
|
||||
return NULL;
|
||||
|
||||
inst->ring = ringbufferCreate(capacity);
|
||||
if (inst->ring == NULL) {
|
||||
free(inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mutexInit(&inst->mut);
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
uint32_t lringbufferCapacity(locked_ringbuffer_t instance)
|
||||
{
|
||||
return instance->ring->capacity;
|
||||
}
|
||||
|
||||
uint32_t lringbufferUsed(locked_ringbuffer_t instance)
|
||||
{
|
||||
int used;
|
||||
mutexLock(&instance->mut);
|
||||
used = ringbufferUsed(instance->ring);
|
||||
mutexUnlock(&instance->mut);
|
||||
return used;
|
||||
}
|
||||
|
||||
bool_t lringbufferEnqueue(locked_ringbuffer_t instance, uint8_t item)
|
||||
{
|
||||
int ret;
|
||||
mutexLock(&instance->mut);
|
||||
ret = ringbufferEnqueue(instance->ring, item);
|
||||
mutexUnlock(&instance->mut);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t lringbufferDequeue(locked_ringbuffer_t instance, uint8_t *item)
|
||||
{
|
||||
int ret;
|
||||
mutexLock(&instance->mut);
|
||||
ret = ringbufferDequeue(instance->ring, item);
|
||||
mutexUnlock(&instance->mut);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lringbufferDestroy(locked_ringbuffer_t instance){
|
||||
mutexFree(&instance->mut);
|
||||
ringbufferDestroy(instance->ring);
|
||||
instance->ring = NULL;
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void lringbufferDebug(locked_ringbuffer_t instance)
|
||||
{
|
||||
mutexLock(&instance->mut);
|
||||
ringbufferDebug(instance->ring);
|
||||
mutexUnlock(&instance->mut);
|
||||
}
|
||||
|
||||
bool_t lringbufferIsEmpty(locked_ringbuffer_t instance)
|
||||
{
|
||||
bool_t ret;
|
||||
mutexLock(&instance->mut);
|
||||
ret = ringbufferIsEmpty(instance->ring);
|
||||
mutexUnlock(&instance->mut);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t lringbufferIsFull(locked_ringbuffer_t instance)
|
||||
{
|
||||
bool_t ret;
|
||||
mutexLock(&instance->mut);
|
||||
ret = ringbufferIsFull(instance->ring);
|
||||
mutexUnlock(&instance->mut);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,15 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdarg.h"
|
||||
#include "wait.h"
|
||||
|
||||
typedef struct ringbuffer_instance_t* ringbuffer_t;
|
||||
typedef struct ringbuffer_instance_t *ringbuffer_t;
|
||||
|
||||
ringbuffer_t ringbufferCreate(uint32_t capacity);
|
||||
uint32_t ringbufferCapacity(ringbuffer_t instance);
|
||||
uint32_t ringbufferUsed(ringbuffer_t instance);
|
||||
bool_t ringbufferEnqueue(ringbuffer_t instance, uint8_t item);
|
||||
bool_t ringbufferDequeue(ringbuffer_t instance, uint8_t* item);
|
||||
bool_t ringbufferDequeue(ringbuffer_t instance, uint8_t *item);
|
||||
void ringbufferDestroy(ringbuffer_t instance);
|
||||
void ringbufferDebug(ringbuffer_t instance);
|
||||
bool_t ringbufferEmpty(ringbuffer_t instance);
|
||||
bool_t ringbufferFull(ringbuffer_t instance);
|
||||
bool_t ringbufferIsEmpty(ringbuffer_t instance);
|
||||
bool_t ringbufferIsFull(ringbuffer_t instance);
|
||||
|
||||
typedef struct locked_ringbuffer_instance_t *locked_ringbuffer_t;
|
||||
|
||||
locked_ringbuffer_t lringbufferCreate(uint32_t capacity);
|
||||
uint32_t lringbufferCapacity(locked_ringbuffer_t instance);
|
||||
uint32_t lringbufferUsed(locked_ringbuffer_t instance);
|
||||
bool_t lringbufferEnqueue(locked_ringbuffer_t instance, uint8_t item);
|
||||
bool_t lringbufferDequeue(locked_ringbuffer_t instance, uint8_t *item);
|
||||
void lringbufferDestroy(locked_ringbuffer_t instance);
|
||||
void lringbufferDebug(locked_ringbuffer_t instance);
|
||||
bool_t lringbufferIsEmpty(locked_ringbuffer_t instance);
|
||||
bool_t lringbufferIsFull(locked_ringbuffer_t instance);
|
||||
|
52
core/uaccess.c
Normal file
52
core/uaccess.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "assert.h"
|
||||
#include "mmuContext.h"
|
||||
#include "paging.h"
|
||||
#include "thread.h"
|
||||
#include "uaccess.h"
|
||||
|
||||
static int bindtoUserContext()
|
||||
{
|
||||
struct thread *currentThread;
|
||||
struct mmu_context *ctx;
|
||||
|
||||
currentThread = getCurrentThread();
|
||||
assert(NULL != currentThread->process);
|
||||
|
||||
/* Switch to the user's address space */
|
||||
ctx = processGetMMUContext(currentThread->process);
|
||||
return threadChangeCurrentContext(ctx);
|
||||
}
|
||||
|
||||
static int unbindUserContext()
|
||||
{
|
||||
return threadChangeCurrentContext(NULL);
|
||||
}
|
||||
|
||||
static int memcpyUserMemNoCheck(vaddr_t dest, vaddr_t src, size_t size)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
ret = bindtoUserContext();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
memcpy((void *)dest, (void *)src, size);
|
||||
|
||||
ret = unbindUserContext();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size)
|
||||
{
|
||||
|
||||
if ((uint)from < PAGING_BASE_USER_ADDRESS)
|
||||
return -EPERM;
|
||||
if ((uint)from > PAGING_TOP_USER_ADDRESS - size)
|
||||
return -EPERM;
|
||||
|
||||
return memcpyUserMemNoCheck(to, from, size);
|
||||
}
|
5
core/uaccess.h
Normal file
5
core/uaccess.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size);
|
Loading…
Reference in New Issue
Block a user