Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- I see the issue. It seems that `current_thread` is not properly initialized, which is leading to a segmentation fault in `mythread_exit`.
- Let's fix the code. I'll provide a modified version with the necessary corrections.
- ```c
- #define _GNU_SOURCE
- #include "mythread.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <sched.h>
- #include <setjmp.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <sys/mman.h>
- #define MAX_THREADS 10 // Define the maximum number of threads
- #define STACK_SIZE (1 << 20) // 1MB stack size, adjust as needed
- int NUM_ALIVE_THREADS = 1;
- int THREAD_COMPLETED = 0;
- int current_thread = 0;
- mythread_t* threads[MAX_THREADS]; // Array to hold thread pointers
- void* routine_wrapper(void *arg){
- mythread_t* t = (mythread_t *)arg;
- setjmp(t->env); // Save the thread's context
- t->res = t->start_routine(t->arg);
- t->completed = 1;
- mythread_exit();
- if (__sync_fetch_and_add(&THREAD_COMPLETED, 1) == NUM_ALIVE_THREADS - 1) {
- // All threads completed, resume the main thread
- __sync_synchronize();
- longjmp(t->env, 1); // Jump back to the main thread
- }
- else {
- pause(); // Suspend the current thread until all other threads complete
- }
- }
- void schedule() {
- int start_thread = current_thread;
- do {
- current_thread = (current_thread + 1) % MAX_THREADS;
- if (threads[current_thread] != NULL && threads[current_thread]->joined && threads[current_thread]->active && !threads[current_thread]->completed) {
- // Switch to this thread
- longjmp(threads[current_thread]->env, 1);
- }
- } while (current_thread != start_thread);
- }
- void mythread_yield() {
- threads[current_thread]->active = 0; // Mark current thread as inactive
- schedule(); // Find the next thread to execute
- threads[current_thread]->active = 1; // Mark next thread as active
- }
- int mythread_create(mythread_t *thread, void *(*start_routine)(void *), void *arg) {
- thread->arg = arg;
- thread->stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (thread->stack == MAP_FAILED) {
- perror("mmap");
- return -1;
- }
- thread->start_routine = start_routine;
- if (clone((int (*)(void *)) routine_wrapper, (char*)thread->stack + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD, thread) == -1) {
- perror("clone");
- return -1;
- }
- thread->joined = 1;
- thread->completed = 0;
- thread->active = 1; // Mark the thread as active
- threads[NUM_ALIVE_THREADS - 1] = thread; // Add the thread to the array
- return 0;
- }
- void mythread_detach(mythread_t *t) {
- t->joined = 0;
- }
- int mythread_join(mythread_t *thread, void **ret_val) {
- if (thread->joined == 0) {
- return -1; // Thread is not joinable
- }
- while (thread->completed == 0) {
- sched_yield(); // Suspend the current thread until the thread completes
- }
- if (ret_val != NULL) {
- *ret_val = thread->res;
- }
- munmap(thread->stack, STACK_SIZE); // Free the stack memory
- return 0;
- }
- void mythread_exit() {
- threads[current_thread]->active = 0; // Mark current thread as inactive
- if (__sync_fetch_and_add(&NUM_ALIVE_THREADS, -1) != 1) {
- // There are other threads, switch to another thread
- mythread_yield();
- }
- else {
- exit(0);
- }
- }
- ```
- In this code, I have ensured that `current_thread` starts at 0, and I've corrected the placement of the thread in the `threads` array. Additionally, I've adjusted the initialization of `NUM_ALIVE_THREADS`. Please test this code and let me know if you encounter any further issues.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement