Skip to content

Commit

Permalink
lkl: let atomic ops outsourced
Browse files Browse the repository at this point in the history
This will allow us to reimplpement atomic ops with lock/touch/unlock way
if underlying hosts don't support a particular atomic ops.

Signed-off-by: Hajime Tazaki <[email protected]>
  • Loading branch information
thehajime committed Nov 21, 2016
1 parent a4c9c32 commit 0865053
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 12 deletions.
7 changes: 7 additions & 0 deletions arch/lkl/include/uapi/asm/host_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,11 @@ int lkl_is_running(void);
int lkl_printf(const char *, ...);
void lkl_bug(const char *, ...);

/* atomic ops */
int lkl__sync_fetch_and_sub(int *ptr, int value);
int lkl__sync_fetch_and_add(int *ptr, int value);
long lkl__sync_fetch_and_or(long *ptr, long value);
long lkl__sync_fetch_and_and(long *ptr, long value);
void lkl__sync_synchronize(void);

#endif
2 changes: 1 addition & 1 deletion arch/lkl/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extra-y := vmlinux.lds

obj-y = setup.o threads.o irq.o time.o syscalls.o misc.o console.o \
syscalls_32.o cpu.o
syscalls_32.o cpu.o atomic.o
86 changes: 86 additions & 0 deletions arch/lkl/kernel/atomic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/host_ops.h>

#if defined(__ARMEL__)
static void *atomic_lock;

long lkl__sync_fetch_and_or(long *ptr, long value)
{
lkl_ops->sem_down(atomic_lock);
*ptr = value;
lkl_ops->sem_up(atomic_lock);
return 0;
}

long lkl__sync_fetch_and_and(long *ptr, long value)
{
int tmp;

lkl_ops->sem_down(atomic_lock);
tmp = *ptr;
*ptr *= value;
lkl_ops->sem_up(atomic_lock);
return tmp;
}

int lkl__sync_fetch_and_add(int *ptr, int value)
{
int tmp;

lkl_ops->sem_down(atomic_lock);
tmp = *ptr;
*ptr += value;
lkl_ops->sem_up(atomic_lock);
return tmp;
}

int lkl__sync_fetch_and_sub(int *ptr, int value)
{
int tmp;

lkl_ops->sem_down(atomic_lock);
tmp = *ptr;
*ptr -= value;
lkl_ops->sem_up(atomic_lock);
return tmp;
}

void lkl__sync_synchronize(void)
{
}

static int __init lkl_atomic_ops_init(void)
{
atomic_lock = lkl_ops->sem_alloc(1);
return 0;
}
early_initcall(lkl_atomic_ops_init);

#else
long lkl__sync_fetch_and_or(long *ptr, long value)
{
return __sync_fetch_and_or(ptr, value);
}

long lkl__sync_fetch_and_and(long *ptr, long value)
{
return __sync_fetch_and_and(ptr, value);
}

int lkl__sync_fetch_and_add(int *ptr, int value)
{
return __sync_fetch_and_add(ptr, value);
}

int lkl__sync_fetch_and_sub(int *ptr, int value)
{
return __sync_fetch_and_sub(ptr, value);
}

void lkl__sync_synchronize(void)
{
return __sync_synchronize();
}
#endif

8 changes: 4 additions & 4 deletions arch/lkl/kernel/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static int __cpu_try_get_lock(int n)
{
lkl_thread_t self;

if (__sync_fetch_and_add(&cpu.shutdown_gate, n) >= MAX_THREADS)
if (lkl__sync_fetch_and_add(&cpu.shutdown_gate, n) >= MAX_THREADS)
return -2;

lkl_ops->mutex_lock(cpu.lock);
Expand All @@ -89,7 +89,7 @@ static void __cpu_try_get_unlock(int lock_ret, int n)
{
if (lock_ret >= -1)
lkl_ops->mutex_unlock(cpu.lock);
__sync_fetch_and_sub(&cpu.shutdown_gate, n);
lkl__sync_fetch_and_sub(&cpu.shutdown_gate, n);
}

void lkl_cpu_change_owner(lkl_thread_t owner)
Expand Down Expand Up @@ -173,7 +173,7 @@ int lkl_cpu_try_run_irq(int irq)

void lkl_cpu_shutdown(void)
{
__sync_fetch_and_add(&cpu.shutdown_gate, MAX_THREADS);
lkl__sync_fetch_and_add(&cpu.shutdown_gate, MAX_THREADS);
}

void lkl_cpu_wait_shutdown(void)
Expand All @@ -184,7 +184,7 @@ void lkl_cpu_wait_shutdown(void)

static void lkl_cpu_cleanup(bool shutdown)
{
while (__sync_fetch_and_add(&cpu.shutdown_gate, 0) > MAX_THREADS)
while (lkl__sync_fetch_and_add(&cpu.shutdown_gate, 0) > MAX_THREADS)
;

if (shutdown)
Expand Down
8 changes: 4 additions & 4 deletions arch/lkl/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ static inline unsigned long test_and_clear_irq_index_status(void)
{
if (!irq_index_status)
return 0;
return __sync_fetch_and_and(&irq_index_status, 0);
return lkl__sync_fetch_and_and(&irq_index_status, 0);
}

static inline unsigned long test_and_clear_irq_status(int index)
{
if (!&irq_status[index])
return 0;
return __sync_fetch_and_and(&irq_status[index], 0);
return lkl__sync_fetch_and_and(&irq_status[index], 0);
}

void set_irq_pending(int irq)
{
int index = irq / IRQ_STATUS_BITS;
int bit = irq % IRQ_STATUS_BITS;

__sync_fetch_and_or(&irq_status[index], BIT(bit));
__sync_fetch_and_or(&irq_index_status, BIT(index));
lkl__sync_fetch_and_or(&irq_status[index], BIT(bit));
lkl__sync_fetch_and_or(&irq_index_status, BIT(index));
}

static struct irq_info {
Expand Down
6 changes: 3 additions & 3 deletions arch/lkl/kernel/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
}

if (_prev->dead) {
__sync_fetch_and_sub(&threads_counter, 1);
lkl__sync_fetch_and_sub((int *)&threads_counter, 1);
lkl_ops->thread_exit();
}

Expand Down Expand Up @@ -193,7 +193,7 @@ int copy_thread(unsigned long clone_flags, unsigned long esp,
return -ENOMEM;
}

__sync_fetch_and_add(&threads_counter, 1);
lkl__sync_fetch_and_add((int *)&threads_counter, 1);

return 0;
}
Expand All @@ -220,7 +220,7 @@ void threads_init(void)

void threads_cnt_dec(void)
{
__sync_fetch_and_sub(&threads_counter, 1);
lkl__sync_fetch_and_sub((int *)&threads_counter, 1);
}

void threads_cleanup(void)
Expand Down

0 comments on commit 0865053

Please sign in to comment.