Commits

Paweł Wieczorek committed 77b4cd3

* dodanie zalazka unix_ctx_ucontext

Comments (0)

Files changed (9)

 SRCS= ${LIB_SRC} ${SUPPORT_SRC}
 LIB_SRC=\
     lib/main.c\
+    lib/thread.c\
 
 EXAMPLE_SRC=\
     examples/ex01.c\
     examples/ex02.c\
-    
+
+SUPPORT_SRC=\
+    support/unix_ctx_ucontext.c\
+
 OBJS= ${SRCS:%.c=%.o}
 EXAMPLES= ${EXAMPLE_SRC:%.c=%}
-.SUFFIXES: .o .c.o .c
+.SUFFIXES: .c.o .c
 
 all: ${LIBNAME} examples
 
     pwuthread_setschedtype(PWUTHREAD_SCHED_COOPERATIVE, NULL);
     pwuthread_create(&t0, NULL, tmain0, NULL);
     pwuthread_create(&t1, NULL, tmain1, NULL);
-    pwuthread_join(&t0);
-    pwuthread_join(&t1);
+    pwuthread_join(t0, NULL);
+    pwuthread_join(t1, NULL);
     return 0;
 }
 

include/pwuthread/ctx.h

 #ifndef PWUTHREAD_CTX_H
 #define PWUTHREAD_CTX_H
 
-void pwuthread_ctx_create(pwuthread_ctx_t *ctx, pwuthread_main_f *func);
-void pwuthread_ctx_setstack(pwuthread_ctx_t *ctx, void *addr, size_t l);
-void pwuthread_ctx_switch(pwuthread_ctx_t *ctx0, pwuthread_ctx_t *ctx1);
+int pwuthread_ctx_init(void);
+int pwuthread_ctx_create(pwuthread_t t, pwuthread_main_f *func, void *sa, size_t sl);
+int pwuthread_ctx_switch(pwuthread_ctx_t ctx0, pwuthread_ctx_t ctx1);
+int pwuthread_ctx_detach(pwuthread_ctx_t ctx);
 
 #endif

include/pwuthread/mainapi.h

 
 int pwuthread_setcancelstate(int state, int *oldstate);
 int pwuthread_setcanceltype(int type, int *oldtype);
-int pwuthread_setschedtype(int schedtype);
+int pwuthread_setschedtype(int schedtype, int *oldschedtype);
 int pwuthread_join(pwuthread_t t, void **);
 int pwuthread_cancel(pwuthread_t t);
 int pwuthread_exit(pwuthread_t t, void *);

include/pwuthread/private.h

 #include "types.h"
 #include "mainapi.h"
 #include "ctx.h"
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct pwuthread {
+    pwuthread_ctx_t context;
+    void *main_arg;
+    void *main_ret;
+    pwuthread_main_f *main;
+};
 
 void pwuthread_log(const char *fmt, ...);
 int pwuthread_init(void);
 
+#define PWUTHREAD_MALLOC(type) (type*)malloc(sizeof(type))
+#define PWUTHREAD_ICALL(c) ( (err = c) ) 
 #endif
 #include "pwuthread/private.h"
 
+static int initialized = 0;
+static int sched_type = PWUTHREAD_SCHED_PREEMPTIVE;
+
 int
 pwuthread_init(void)
 {
+    int err;
+    if (initialized) return 0;
+    if (PWUTHREAD_ICALL(pwuthread_ctx_init())) {
+        return err;
+    }
+    initialized = 1;
     return 0;
 }
 
+int
+pwuthread_setschedtype(int st, int *ost)
+{
+    int r;
+    if (initialized) return EBUSY;
+    switch (st) {
+        case PWUTHREAD_SCHED_PREEMPTIVE:
+        case PWUTHREAD_SCHED_COOPERATIVE:
+            if (ost) *ost = sched_type;
+            sched_type = st;
+            r = 0;
+            break;
+        default:
+            r = EINVAL;
+            break;
+    }
+    return r;
+}
 
+#include "pwuthread/private.h"
+#include <errno.h>
+
+int
+pwuthread_create(pwuthread_t *t, pwuthread_attr_t *a,
+    pwuthread_main_f *func, void *arg)
+{
+    return ENOTSUP;
+}
+
+int
+pwuthread_join(pwuthread_t t, void **arg)
+{
+    return ENOTSUP;
+}
+
+int
+pwuthread_detach(pwuthread_t t)
+{
+    return ENOTSUP;
+}
+
+void
+pwuthread_yield(void)
+{
+}
+

support/unix_ctx_setjmp.c

+#include "pwuthread/private.h"
+#include <setjmp.h>
+
+struct pwuthread_ctx {
+    jmp_buf jb;
+    pwuthread_main_f *func;
+};
+
+int
+pwuthread_ctx_create(pwuthread_t t, pwuthread_main_f *func,
+    void *sa, size_t sl )
+{
+    return ENOTSUP;
+}
+
+int
+pwuthread_ctx_switch(pwuthread_ctx_t ctx0, pwuthread_ctx_t ctx1)
+{
+    return ENOTSUP;
+}
+
+int
+pwuthread_ctx_detach(pwuthread_ctx_t ctx)
+{
+    return ENOTSUP;
+}
+

support/unix_ctx_ucontext.c

+#include "pwuthread/private.h"
+#include <ucontext.h>
+
+struct pwuthread_ctx {
+    ucontext_t uctx;
+};
+
+enum {
+    EXIT_TRAMPOLINE_STKSZ = 1024*16
+};
+
+typedef void starter(void);
+
+static void _thread_wraper(pwuthread_t t);
+static void _thread_exit();
+static ucontext_t exit_trampoline;
+
+void
+_thread_wraper(pwuthread_t t)
+{
+    t->main_ret = t->main(t->main_arg);
+}
+
+void
+_thread_exit(void)
+{
+}
+
+int
+pwuthread_ctx_init(void)
+{
+    getcontext(&exit_trampoline);
+    makecontext(&exit_trampoline, _thread_exit, 0);
+    exit_trampoline.uc_stack.ss_sp = malloc(EXIT_TRAMPOLINE_STKSZ);
+    if (exit_trampoline.uc_stack.ss_sp == NULL) return errno;
+    exit_trampoline.uc_stack.ss_size = EXIT_TRAMPOLINE_STKSZ;
+    exit_trampoline.uc_stack.ss_flags = 0;
+    exit_trampoline.uc_link = NULL;
+    return 0;
+}
+
+int
+pwuthread_ctx_create(pwuthread_t t, pwuthread_main_f *func,
+    void *sa, size_t sl )
+{
+    t->context = PWUTHREAD_MALLOC(struct pwuthread_ctx);
+    if (t->context == NULL) return errno;
+    getcontext(&t->context->uctx);
+    makecontext(&t->context->uctx, (starter*)_thread_wraper, 1, t);
+    t->context->uctx.uc_stack.ss_sp = sa;
+    t->context->uctx.uc_stack.ss_size = sl;
+    t->context->uctx.uc_stack.ss_flags = 0;
+    t->context->uctx.uc_link = &exit_trampoline;
+    return 0;
+}
+
+int
+pwuthread_ctx_switch(pwuthread_ctx_t ctx0, pwuthread_ctx_t ctx1)
+{
+    return ENOTSUP;
+}
+
+int
+pwuthread_ctx_detach(pwuthread_ctx_t ctx)
+{
+    return ENOTSUP;
+}
+