bupt_os_lab1

bupt_os lab1作业

1.编写代码

uthread.h

#ifndef UTHREAD_H
#define UTHREAD_H

#define STACK_SIZE 4096

enum thread_state {
    THREAD_INIT,
    THREAD_RUNNING,
    THREAD_STOP,
    THREAD_SUSPENDED,
};

struct context {
    long long rip, rsp, rbp, rbx, r12, r13, r14, r15;
    long long rdi, rsi, rdx;
};

struct uthread {
    char stack[STACK_SIZE];
    struct context context;
    enum thread_state state;
    const char *name;
};

void init_uthreads();
void schedule();
struct uthread *uthread_create(void (*func)(void *), void *arg, const char* thread_name);
void uthread_resume(struct uthread *tcb);
long long uthread_yield();
void thread_destroy(struct uthread *tcb);

#endif

uthread.c

#include "uthread.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>

#define STACK_SIZE 4096

static struct uthread *current_thread = NULL;
static struct uthread *main_thread = NULL;
static struct uthread *thread_queue[10];
static int thread_count = 0;
static int current_index = 0;

jmp_buf main_context;

void thread_switch(struct context *from, struct context *to);

void _uthread_entry(struct uthread *tcb, void (*thread_func)(void *), void *arg) {
    tcb->state = THREAD_RUNNING;
    thread_func(arg);
    tcb->state = THREAD_STOP;
    longjmp(main_context, 1); // 切换回主线程
}

struct uthread *uthread_create(void (*func)(void *), void *arg, const char* thread_name) {
    struct uthread *uthread = malloc(sizeof(struct uthread));
    if (!uthread) {
        printf("Error allocating memory for thread\n");
        exit(1);
    }
    memset(uthread, 0, sizeof(struct uthread));

    // 初始化栈指针
    char *stack_top = uthread->stack + STACK_SIZE;
    uthread->context.rsp = (long long)stack_top - 8; // 假设我们需要留出8字节的空间

    uthread->context.rip = (long long)_uthread_entry;
    uthread->context.rdi = (long long)uthread;
    uthread->context.rsi = (long long)func;
    uthread->context.rdx = (long long)arg;
    uthread->state = THREAD_INIT;
    uthread->name = thread_name;

    thread_queue[thread_count++] = uthread;
    return uthread;
}
void schedule() {
    if (setjmp(main_context) == 0) { // 初次调用或从上一个线程返回
        while (thread_count > 0) {
            current_thread = thread_queue[current_index];
            if (current_thread->state == THREAD_STOP) {
                // 移除停止的线程
                free(current_thread);
                for (int i = current_index; i < thread_count - 1; i++) {
                    thread_queue[i] = thread_queue[i + 1];
                }
                thread_queue[--thread_count] = NULL;
                if (current_index >= thread_count) {
                    current_index = 0;
                }
                continue;
            }
            if (current_thread->state == THREAD_INIT) {
                current_thread->state = THREAD_RUNNING;
                if (!setjmp(main_context)) {
                    thread_switch(&main_thread->context, &current_thread->context);
                }
            } else {
                uthread_resume(current_thread);
            }
            current_index = (current_index + 1) % thread_count;
        }
    }
}

void uthread_resume(struct uthread *tcb) {
    if (setjmp(main_context) == 0) {
        current_thread = tcb;
        thread_switch(&main_thread->context, &tcb->context);
    }
}

long long uthread_yield() {
    current_thread->state = THREAD_SUSPENDED;
    if (!setjmp(main_context)) {
        thread_switch(&current_thread->context, &main_thread->context);
    }
    return 0;
}

// 假设的上下文切换函数,实际实现依赖于具体的架构和编译器
void init_uthreads() {
    main_thread = malloc(sizeof(struct uthread));
    if (!main_thread) {
        printf("Error allocating memory for main thread\n");
        exit(1);
    }
    memset(main_thread, 0, sizeof(struct uthread));
    main_thread->state = THREAD_RUNNING;
    current_thread = main_thread;
}

void uthread_destroy(struct uthread *tcb) {
    free(tcb);
}

2.在vscode上先暂存再commit

image-20241030230640529

commit

image-20241031143017380

3.生成patch

查看一下分支树

image-20241030231229555

对origin/lab1生成patch

image-20241031142618012

git format-patch origin/lab1

然后将0001-try2.patch上传提交即可

posted @ 2024-10-31 14:32  vast_joy  阅读(4)  评论(0编辑  收藏  举报