typedef struct в typedef struct присвоение переменных не работает в c - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь использовать переменную в структуре typedef, которая хранится в другой структуре typedef. Как только я сохраню этот указатель внутри массива указателей, идентификатор переменной procHeaader теряется.

#include <stdlib.h>
#include <Arduino.h>
#include "Proc.h"
#include "../../Fat/src/Fat.h"

/*
    creates a process table with a size of MAX_PROC_COUNT
*/
ProcTable * createProcTable() {
    ProcTable * procTable = (ProcTable *)malloc(sizeof(ProcTable));
    procTable->procCount = 0;
    return procTable;
}

/*
    dumps the process table
*/
void dumpProcessTable(ProcTable * table) {
    Serial.println("Processes");

    if(table->procCount < 1) {
        Serial.println("---------------");
        Serial.println("no procs running");
        return;
    }

    for(int i = 0; i < table->procCount; i++) {

        Serial.println("---------------"); 
        Serial.println("pid | quantum");
        Serial.print(table->procs[i]->header->id); 
        Serial.write(" ");
        Serial.print(table->procs[i]->quantum);        
        Serial.write("\n");

    }
}
/*
    creates a process in the paused state
*/
Process * createProcess(ProcTable * table, Fat * fat, char * fileName) {
    Process * proc = (Process*)malloc(sizeof(Process));
    proc->header = (ProcHeader*)malloc(sizeof(ProcHeader));
    proc->mmu = (MMU *)malloc(sizeof(MMU));
    proc->header->id = table->procCount;
    proc->header->state = RUNNING;
    proc->quantum = MAX_QUANTUM; //TODO: change this based on how big the binary that gets loaded into it is
    loadProcExecutable(proc, fat, fileName);

    table->procs[table->procCount] = proc;
    table->procCount++;

    return proc;
}

Process * findProc(ProcTable * table, int pid) {

    for(int i = 0; i <= table->procCount; i++) {
        if(table->procs[i]->header->id == pid) {
            return table->procs[i];
        } 
    }

    Serial.println("Tried to lookup non existent process. terminating operation.");

}

/*
    cuts a process specified with pid from the proc table and decrements the procCounter
*/
void deleteProc(ProcTable * table, int pid) {

    Process * procs[MAX_PROC_COUNT] = {};

    for(int i = 0; i < table->procCount; i++) {
        if(table->procs[i]->header->id != pid) {
            procs[i] = table->procs[i];
        }
    }

    memcpy(table->procs, procs, MAX_PROC_COUNT);
    table->procCount--;

}


/*
    sets the state of a process
    states:
            0: paused
            1: running
            2: terminated
    this should also be used to outright kill processes
*/
void setProcState(ProcTable * table, int pid, int state) {

    Process * proc = findProc(table, pid);

    switch(state) {
        case PAUSED:
            proc->header->state = PAUSED;
            break;
        case RUNNING:
            proc->header->state = RUNNING;
            break;
        case TERMINATED:
            deleteProc(table, proc->header->id);
            break;
    }

}

/*
    Loads a program into a given process space
*/
void loadProcExecutable(Process * proc, Fat * fat, char * fileName) {

    fileInfo * filePtr = (fileInfo *)malloc(sizeof(fileInfo));
    int fileIndex = findFileByName(fileName, fat->fileCount);
    char * fileContents;

    if(fileIndex == -1) {
        Serial.print(fileName);
        Serial.print(": no such file\n");
        return;
    }

    getFATEntry(fileIndex, filePtr);
    getFileData(*filePtr, fileContents);
    writeMemoryChunk(proc->mmu, fileContents, 0, sizeof(fileContents)/sizeof(char));

}

void startNextProc(ProcTable * table) {
    table->procs[table->procCount-1]->header->state == RUNNING;
}

/*
    updates all processes timers. If any process has run out of time, it will be killed
*/
void updateProcessQuantums(ProcTable * table, int cycleTime) {
    if(table->procCount == 0) {
        return;
    }
    for(int i = 0; i <= table->procCount; i++) {
        if(table->procs[i]->quantum - cycleTime < 0) {
            if(!table->procs[i]->interpreter->finished) {
                table->procs[i]->header->state = PAUSED;
            }
            //dump a message
            Serial.print("killing pid: ");
            Serial.print(table->procs[i]->header->id);
            Serial.println(" quantum expired");

            //kill the process
            setProcState(table, table->procs[i]->header->id, TERMINATED);

            //see what proc is next in line
            startNextProc(table);
            return;
        }
        if(table->procs[i]->header->state == PAUSED) {

            continue;

        }
        if(table->procs[i]->header->state == RUNNING) {
            table->procs[i]->quantum -= 1;
            // InterpretOneCycle(table->procs[i]->interpreter, &table->procs[i]->header->pc, table->procs[i]->mmu->memUsed);

            // if(table->procs[i]->interpreter->finished) {

            //     setProcState(table, table->procs[i]->header->id, TERMINATED);
            //     startNextProc(table);  

            // }
        }
    }
    return;
}

заголовочный файл:


#define PROC_MEM_SIZE 0x200
#define MAX_PROC_COUNT 0x9
#define MAX_QUANTUM 1000000 //ticks
#define PAUSED 0
#define RUNNING 1
#define TERMINATED 2


typedef struct {
    char * stack;
    int id;
    int state; 
    int sp;
    int loopAddr; 
    int pc;
} ProcHeader;

typedef struct {
    ProcHeader * header;        //contains global information about the process
    unsigned int memOffset;     //this is for the interpreter to know where to execute its opcodes
    long int quantum;                //time slot for the process
    Interpreter * interpreter;  //Interpreter that will execute opcodes
    MMU * mmu;                  //Manager for process memory
} Process;

typedef struct {
    Process * procs[MAX_PROC_COUNT];
    int procCount;
} ProcTable;

ProcTable * createProcTable();
Process * createProcess(ProcTable * table, Fat * fat, char * filename);
void setProcState(ProcTable * table, int pid, int state);
void dumpProcessTable(ProcTable * table);
void updateProcessQuantums(ProcTable * table, int cycleTime);
void loadProcExecutable(Process * proc, Fat * fat, char * fileName);

метод вызывающего абонента:

Kernel * initKernel() {
    Kernel * kernel = (Kernel*)malloc(sizeof(Kernel));
    kernel->procTable = createProcTable();
    kernel->fat = createFAT();

    return kernel;
}

заголовок вызывающего абонента:

typedef struct {
    ProcTable * procTable;
    Fat * fat;
    int debugMode;
    int cycleDuration;
} Kernel;

Kernel * initKernel();
Process * createProcess(ProcTable * table);

Как только я просматриваю записи массива procs, идентификатор процесса, который он возвращает - что-то число. Почему это так?

Для отладки используется следующая функция:

    for(int i = 0; i < table->procCount; i++) {

        Serial.println("---------------"); 
        Serial.println("pid | quantum");
        Serial.print(table->procs[i]->header->id); //returns 1256? 
        Serial.write(" ");
        Serial.print(table->procs[i]->quantum);        
        Serial.write("\n");

    }
...