diff --git a/user/apps/build.mk b/user/apps/build.mk index a623963b..eaee7464 100644 --- a/user/apps/build.mk +++ b/user/apps/build.mk @@ -3,8 +3,7 @@ # found in the LICENSE file. user-apps-dirs = \ - l4test \ - pingpong + posixtest \ ifdef CONFIG_BOARD_STM32F429DISCOVERY user-apps-dirs += \ diff --git a/user/apps/l4test/main.c b/user/apps/l4test/main.c index 2b48cb98..31e46089 100644 --- a/user/apps/l4test/main.c +++ b/user/apps/l4test/main.c @@ -20,7 +20,7 @@ #include "l4test.h" #include "assert.h" -#define STACK_SIZE 512 +#define STACK_SIZE 256 /* where to start allocating RAM */ __USER_BSS static char *free_page; diff --git a/user/apps/posixtest/build.mk b/user/apps/posixtest/build.mk new file mode 100644 index 00000000..c08c6ff8 --- /dev/null +++ b/user/apps/posixtest/build.mk @@ -0,0 +1,6 @@ +# Copyright (c) 2013 The F9 Microkernel Project. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +user-apps-posixtest-y = \ + main.o \ diff --git a/user/apps/posixtest/main.c b/user/apps/posixtest/main.c new file mode 100644 index 00000000..f42c6dae --- /dev/null +++ b/user/apps/posixtest/main.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +/* posix layer */ +#include + +#define STACK_SIZE 512 + +__USER_DATA pthread_mutex_t mutex; + +__USER_DATA int shared = 0; + +__USER_TEXT void *child_thread2(void *args) +{ + printf("child task 2 start\n"); + + while(1) { + shared = shared + 1; + printf("task 2: %d\n", shared); + L4_Sleep(L4_TimePeriod(1000)); + } + + return 0; +} + +__USER_TEXT void *child_thread1(void *args) +{ + printf("child task 1 start\n"); + pthread_create(NULL, NULL, child_thread2, NULL); + + for(int i = 0; i <= 10; i++) { + printf("%d\n", 10 - i); + L4_Sleep(L4_TimePeriod(500)); + } + + for(int i = 0; i <= 10; i++) { + printf("%d\n", 10 - i); + L4_Sleep(L4_TimePeriod(500)); + } + + while(1) { + L4_Sleep(L4_Never); + } + + return 0; +} + +static __USER_TEXT void *main(void *user) +{ + printf("\nPosix Layer test starts\n"); + mutex = 0; + pthread_create(NULL, NULL, child_thread1, NULL); + + while(1) + L4_Sleep(L4_Never); + + return NULL; +} + +DECLARE_USER( + 255, + posixtest, + main, + DECLARE_FPAGE(0x0, 4 * (UTCB_SIZE + STACK_SIZE)) + DECLARE_FPAGE(0x0, 512) +); diff --git a/user/include/libposix/libposix.h b/user/include/libposix/libposix.h new file mode 100644 index 00000000..df09c959 --- /dev/null +++ b/user/include/libposix/libposix.h @@ -0,0 +1,6 @@ +#ifndef __LIBPOSIX_H__ +#define __LIBPOSIX_H__ + +int fork(void); + +#endif diff --git a/user/include/libposix/pthread.h b/user/include/libposix/pthread.h new file mode 100644 index 00000000..40eb96ff --- /dev/null +++ b/user/include/libposix/pthread.h @@ -0,0 +1,21 @@ +#ifndef __PTHREAD_H__ +#define __PTHREAD_H__ + +#include + +int pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void*), void *restrict arg); +int pthread_detach(pthread_t thread); +void pthread_exit(void *value_ptr); +int pthread_join(pthread_t thread, void **value_ptr); +int pthread_mutex_init(pthread_mutex_t *mutex, + const pthread_mutexattr_t *restrict attr); +int pthread_mutex_destroy(pthread_mutex_t *mutex); +int pthread_mutex_lock(pthread_mutex_t *mutex); +int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_unlock(pthread_mutex_t *mutex); +int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); + +#endif diff --git a/user/include/libposix/sys/types.h b/user/include/libposix/sys/types.h new file mode 100644 index 00000000..7fa3f41d --- /dev/null +++ b/user/include/libposix/sys/types.h @@ -0,0 +1,17 @@ +#ifndef __TYPES_H_ +#define __TYPES_H_ + +#include + +/* FIXME: This should be moved to time.h */ +struct timespec { + uint64_t nsec; +}; + +/* FIXME: Define proper type for pthread type */ +typedef uint32_t pthread_mutex_t; +typedef uint32_t pthread_mutexattr_t; +typedef uint32_t pthread_t; +typedef uint32_t pthread_attr_t; + +#endif diff --git a/user/include/libposix/unimplemented.h b/user/include/libposix/unimplemented.h new file mode 100644 index 00000000..8356e732 --- /dev/null +++ b/user/include/libposix/unimplemented.h @@ -0,0 +1,18 @@ +#ifndef __UNIMPLEMENTED_H__ +#define __UNIMPLEMENTED_H__ + +#define ESC "\e[" +#define LIGHT_RED ESC "31;1m" +#define BLACK ESC "0m" + +#include + +#define UNIMPLEMENTED() \ + do { \ + printf("%s", LIGHT_RED); \ + printf("\nUnimplemented: %s, at %s:%d", \ + __func__, __FILE__, __LINE__); \ + printf("%s\n", BLACK); \ + } while (0) \ + +#endif diff --git a/user/include/user_runtime.h b/user/include/user_runtime.h index 39c47405..eafc12fa 100644 --- a/user/include/user_runtime.h +++ b/user/include/user_runtime.h @@ -7,6 +7,7 @@ #define USER_RUNTIME_H #include +#include typedef struct user_struct user_struct; typedef void (*user_entry)(user_struct *); diff --git a/user/lib/build.mk b/user/lib/build.mk index ed6cadf9..2906d4b6 100644 --- a/user/lib/build.mk +++ b/user/lib/build.mk @@ -5,3 +5,4 @@ user-lib-dirs = \ l4 \ io \ + libposix \ diff --git a/user/lib/libposix/build.mk b/user/lib/libposix/build.mk new file mode 100644 index 00000000..28c92178 --- /dev/null +++ b/user/lib/libposix/build.mk @@ -0,0 +1,7 @@ +# Copyright (c) 2013 The F9 Microkernel Project. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +user-lib-libposix-y = \ + fork.o \ + pthread.o diff --git a/user/lib/libposix/fork.c b/user/lib/libposix/fork.c new file mode 100644 index 00000000..232d9e6c --- /dev/null +++ b/user/lib/libposix/fork.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int __USER_TEXT fork() +{ + UNIMPLEMENTED(); + return 0; +} diff --git a/user/lib/libposix/pthread.c b/user/lib/libposix/pthread.c new file mode 100644 index 00000000..46a84bee --- /dev/null +++ b/user/lib/libposix/pthread.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include + +int __USER_TEXT pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void*), void *restrict arg) +{ + L4_ThreadId_t tid = pager_create_thread(); + + pager_start_thread(tid, start_routine, NULL); + + return *(int *)&tid; +} + +__USER_TEXT int pthread_detach(pthread_t thread) +{ + return 0; +} + +__USER_TEXT void pthread_exit(void *value_ptr) +{ + return; +} + +__USER_TEXT int pthread_join(pthread_t thread, void **value_ptr) +{ + return 0; +} + +__USER_TEXT int pthread_mutex_init(pthread_mutex_t *mutex, + const pthread_mutexattr_t *restrict attr) +{ + return 0; +} + +__USER_TEXT int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return 0; +} + +__USER_TEXT int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + /* Busy trying */ + while(pthread_mutex_trylock(mutex)); + + return 0; +} + +__USER_TEXT int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + register int result = 1; + + __asm__ __volatile__( + "mov r1, #1\n" + "mov r2, %[mutex]\n" + "ldrex r0, [r2]\n" /* Load value [r2] */ + "cmp r0, #0\n" /* Checking is word set to 1 */ + + "itt eq\n" + "strexeq r0, r1, [r2]\n" + "moveq %[result], r0\n" + : [result] "=r"(result) + : [mutex] "r"(mutex) + : "r0", "r1", "r2"); + + return result; +} + +__USER_TEXT int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + *mutex = 0; + return 0; +} + +__USER_TEXT int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime) +{ + return 0; +} diff --git a/user/root_thread.c b/user/root_thread.c index 0401bf26..ed7bf086 100644 --- a/user/root_thread.c +++ b/user/root_thread.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include