Commits

Anonymous committed fc20eee

première implem avec preemption

Comments (0)

Files changed (1)

 #include "thread.h"
 #include <assert.h>
 #include <queue.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/time.h>
 #include <ucontext.h>
+#include <unistd.h>
 #include <valgrind/valgrind.h>
-// #include <unistd.h>
 
 #define QUEUE_NEXT qnext
 #define QUEUE_HNAME thread_queue
 #define STACK_SIZE (64 * 1024)
+#define ALARM_DELAY 1000
 
 #define DEBUG
 #define TRUE 1
 static unsigned _thread_count = 0;
 static char _lib_init_done = FALSE;
 
+// le bitmask des signaux
+sigset_t sigset;
+
+
 // la runqueue
 static CIRCLEQ_HEAD(QUEUE_HNAME, thread) runqueue = CIRCLEQ_HEAD_INITIALIZER(runqueue);
 
 static int _thread_schedule(void);
 static int _thread_swap(thread_t, thread_t);
 static thread_t _thread_new(void);
+static void _thread_alarm_callback(int sig);
 static void _thread_free(thread_t);
 static void _thread_func_wrap(thread_t);
 static void _thread_lib_destroy(void);
  * ===================================================
  */
 
+void _print_sig_set(const sigset_t *sigset) {
+    int sig;
+
+	fprintf(stderr, "SIGS = {");
+    for (sig = 1; sig < NSIG; sig++) {
+        if (sigismember(sigset, sig)) {
+            fprintf(stderr, "%s, ", strsignal(sig));
+        }
+    }
+	fprintf(stderr, "}\n");
+}
+
+
+static void _thread_alarm_callback(int sig) {
+	#ifdef DEBUG
+	fprintf(stderr, "BEEP! YIELD!\n");
+	#endif
+	// on yield quand on est alarmé
+	thread_yield();
+}
+
+
 static void _thread_lib_init(void) {
 	if(_lib_init_done)
 		return;
 	#endif
 	current_thread = main_thread;
 	CIRCLEQ_INSERT_TAIL(&runqueue, main_thread, QUEUE_NEXT);
+
+	// installation du scheduler alarm
+	// sigset = {}
+	// sigemptyset(&sigset);
+	// sigset = {SIGALRM}
+	// sigaddset(&sigset, SIGALRM);
+	struct sigaction sigstruct;
+	sigstruct.sa_flags = SA_RESTART | SA_ONSTACK;
+	sigstruct.sa_handler = _thread_alarm_callback;
+	if(sigaction(SIGALRM, &sigstruct, NULL) != 0) {
+		perror("_thread_lib_init sigaction");
+		exit(EXIT_FAILURE);
+	}
+
+	// _print_sig_set(&sigset);
+	// on lance
+	ualarm(ALARM_DELAY, 0);
 }
 
 
 	assert(old != new);
 	assert(!new->is_done);
 
+	// current_thread = thread_self();
+	// on prévoit le prochain
+	ualarm(ALARM_DELAY, 0);
+
 	// on swap vraiment !
 	current_thread = new;
 	rv = swapcontext(&(old->context), &(new->context));
 	if(rv != 0) {
 		perror("_thread_swap");
 	}
+
 	return rv;
 }
 
 int thread_yield(void) {
 	_thread_lib_init();
 
-
-	//	thread_t next_thread = this;
 	#ifdef DEBUG
 	thread_t this = thread_self();
 	fprintf(stderr, "I YIELD (current %p)\n", this);