Commits

Anonymous committed 4c2f102 Merge

test + tentative de protéger SIGALRM

Comments (0)

Files changed (2)

 #define QUEUE_NEXT qnext
 #define QUEUE_HNAME thread_queue
 #define STACK_SIZE (64 * 1024)
-#define ALARM_DELAY 1000
+#define ALARM_DELAY 300
 
 #define DEBUG
 #define TRUE 1
 	// libération des globales
 	atexit(_thread_lib_destroy);
 
+	// sigsetmask(SIGALRM);
 	CIRCLEQ_INIT(&runqueue);
+	// sigsetmask(0);
 
 	if(NULL == (main_thread = _thread_new())) {
 		perror("_thread_lib_init");
 	ualarm(ALARM_DELAY, 0);
 
 	// on swap vraiment !
+	// sigsetmask(SIGALRM);
 	current_thread = new;
+	sigsetmask(0);
 	rv = swapcontext(&(old->context), &(new->context));
 
 	if(rv != 0) {
 
 static int _thread_schedule(void) {
 	// trouve le premier thread !is_done
+
+	// sigsetmask(SIGALRM);  // prevent SIGALRM interrupts
 	thread_t this = thread_self();
 	thread_t next_thread = this;
 
 			#ifdef DEBUG
 			fprintf(stderr, "one thread only, no need to swap\n");
 			#endif
+			// sigsetmask(0);
 			return 0;
 		}
 
 		break;
 	}
 
+	// sigsetmask(0);  // release SIGALRM interrupts
 	return _thread_swap(this, next_thread);
 }
 
 	nt->func_ptr = func;
 	nt->func_argv = funcarg;
 
+	// sigsetmask(SIGALRM);  // prevent SIGALRM interrupts
 	CIRCLEQ_INSERT_TAIL(&runqueue, nt, QUEUE_NEXT);
+	// sigsetmask(0);
 
 	// création du contexte
 	makecontext(
 int thread_yield(void) {
 	_thread_lib_init();
 
+	sigsetmask(SIGALRM);
 	#ifdef DEBUG
 	thread_t this = thread_self();
 	fprintf(stderr, "I YIELD (current %p)\n", this);
+	// sigsetmask(0);
 	#endif
 
 	return _thread_schedule();
 	_thread_lib_init();
 
 	int rv = 0;
+
+	// sigsetmask(SIGALRM);  // prevent SIGALRM interrupts
 	thread_t self = thread_self();
 
 	/*
 	while(!thread->is_done) {
 		CIRCLEQ_REMOVE(&runqueue, self, QUEUE_NEXT);
 		thread->waiting_thread = self;
+		// sigsetmask(0);
 		rv = _thread_schedule();
 	}
 
 	if(thread != main_thread) {
 		_thread_free(thread);
 	}
+	// sigsetmask(0);
 
 	#ifdef DEBUG
 	fprintf(stderr, "RETVAL FOR JOIN %d\n", rv);
 void thread_exit(void *retval) {
 	_thread_lib_init();
 
+	// sigsetmask(SIGALRM);
 	thread_t this = thread_self();
 	// on sauvegarde le retour
 	this->retval = retval;
 	if(this == main_thread) {
 
 		do {
+			// sigsetmask(0);
 			thread_yield();
-		} while(!CIRCLEQ_EMPTY(&runqueue));
+			// sigsetmask(SIGALRM);
+			if(CIRCLEQ_EMPTY(&runqueue)) {
+				// sigsetmask(0);
+				break;
+			}
+		} while(TRUE);
 
 		#ifdef DEBUG
 		fprintf(stderr, "MAIN CIRQLEQ EMPTY\n");
 
 	} else {
 
-		// FIXME: inutile ?
 		if(CIRCLEQ_EMPTY(&runqueue)) {
 			#ifdef DEBUG
 			fprintf(stderr, "CIRCLEQ EMPTY I AM THE PTR %p\n", this);
 			setcontext(&(main_thread->context));
 			exit(0);
 		}
+		// sigsetmask(0);
 
 		_thread_schedule();
 
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "thread.h"
+
+/* test avec thread qui prend du temps pour tester la preemption */
+static long heavy;
+
+static void * thfunc(void *dummy __attribute__((unused)))
+{
+  unsigned long i;
+  for(i = 0; i < heavy; i++) {
+    if(i % 2 == 0) {
+      fprintf(stderr, "AUTO YIELD\n");
+      thread_yield();
+    }
+  }
+  thread_exit(NULL);
+}
+
+int main(int argc, char *argv[])
+{
+  int err, i, nb;
+
+  if (argc < 2) {
+    printf("argument manquant: nombre de threads\n");
+    return -1;
+  }
+
+  nb = atoi(argv[1]);
+  heavy = atoi(argv[2]);
+
+  thread_t th[nb];
+  void *res[nb];
+
+  for(i=0; i<nb; i++) {
+    err = thread_create(&(th[i]), thfunc, NULL);
+    assert(!err);
+  }
+
+  for(i=0; i<nb; i++) {
+    err = thread_join(th[i], &(res[i]));
+    assert(!err);
+    assert(res[i] == NULL);
+  }
+
+  printf("%d threads créés et détruits\n", nb);
+  return 0;
+}