I'm student in practicing PintOS Project. In Programming Project 3(Virtual Memory), I got ploblems about "preprocess in compiling" (C program). I had tried all attempt that do my best, but I'm absolutely lost at this point on how to fix it. Finally i come to here, had to ask you about this issue.

error

I finished stack growth part, so I am modifying syscall.c to implement mmap, but got problems in buid process. the spt field is being recognized as an incomplete type and is not being excluded.

current situation

The thread structure in question is declared in thread.h, and the type supplemental_page_table of spt, an element in the thread structure, is declared in vm.h. Above the thread structure in current thread.h #ifdef VM #include "vm/vm.h" is preprocessing the format vm.h. I am currently using the EC2 server(ubuntu 18.04) via SSH connection to VS code, and have tried solutions such as make clean, make, inserting and changing the order of #include preprocessing and forward declaration code, and rebooting + reinstalling EC2, but there is no progress.

Questions

  1. If vm.h, where the spt structure is declared in thread.h, is included before the thread structure, shouldn't it be able to be used without problems?
...
#ifdef VM            // I'm in project3(VM)
#include "vm/vm.h"

...

struct thread {
...
#ifdef VM
    /* Table for whole virtual memory owned by thread. */
    struct supplemental_page_table spt;      // The spt structure is defined in vm.h.
...
/* Print in terminal */
In file included from ../../include/userprog/process.h:4:0,
                 from ../../include/vm/vm.h:7,
                 from ../../vm/vm.c:4:
../../include/threads/thread.h:151:33: error: field ‘spt’ has incomplete type
  struct supplemental_page_table spt;
                                 ^~~
In file included from ../../vm/vm.c:4:0:
../../include/vm/vm.h:200:1: warning: "/*" within comment [-Wcomment]
 /* 현재 프로세스의 메모리 공간을 나타내는 구조체입니다.
  
../../vm/vm.c: In function ‘vm_init’:
../../vm/vm.c:21:23: warning: unused variable ‘start’ [-Wunused-variable]
     struct list_elem *start = list_begin(&frame_table);
                       ^~~~~
../../vm/vm.c: In function ‘vm_alloc_page_with_initializer’:
../../vm/vm.c:84:1: warning: label ‘err’ defined but not used [-Wunused-label]
 err:
 ^~~
../../vm/vm.c: In function ‘spt_insert_page’:
../../vm/vm.c:105:6: warning: unused variable ‘succ’ [-Wunused-variable]
  int succ = false;
      ^~~~
../../vm/vm.c: In function ‘spt_remove_page’:
../../vm/vm.c:111:55: warning: unused parameter ‘spt’ [-Wunused-parameter]
 void spt_remove_page (struct supplemental_page_table *spt, struct page *page) {
                                                       ^~~

...
  1. Additionally, I have a customization called tid_t in process.h that is also defined in thread.h, and I've included it, but it doesn't reference it. I solved this problem by defining it again in process.h ,it is repeated, but I thought I'd ask along the same problem-context as above. For reference, I have the above issue after this.
/* Code in process.h */
#ifndef USERPROG_PROCESS_H
#define USERPROG_PROCESS_H

#include "threads/thread.h"

bool install_page (void *upage, void *kpage, bool writable);
// typedef int tid_t;       // If i remove annotation in this line, going to problem mentioned above

tid_t process_create_initd (const char *file_name);
tid_t process_fork (const char *name, struct intr_frame *if_);
int process_exec (void *f_name);
int process_wait (tid_t);
void process_exit (void);
void process_activate (struct thread *next);

#endif /* userprog/process.h */

/* Print */
In file included from ../../include/vm/vm.h:7:0,
                 from ../../include/threads/thread.h:12,
                 from ../../threads/init.c:24:
../../include/userprog/process.h:9:1: error: unknown type name ‘tid_t’; did you mean ‘size_t’?
 tid_t process_create_initd (const char *file_name);
 ^~~~~
 size_t
/* here is modified code i did, but i think it is not problem */

void *mmap (void *addr, size_t length, int writable, int fd, off_t offset) {
    if (offset % PGSIZE != 0) {
        return NULL;
    }

    if (pg_round_down(addr) != addr || is_kernel_vaddr(addr) || addr == NULL || (long long)length <= 0)
        return NULL;
    
    if (fd == 0 || fd == 1) {
        exit(-1);
    }
    
    if (spt_find_page(&thread_current()->spt, addr))
        return NULL;

    struct file *target = find_file_by_fd(fd);
    if (target == NULL)
        return NULL;

    void * ret = do_mmap(addr, length, writable, target, offset);
    return ret;
}

void munmap (void *addr) {
    do_munmap(addr);
}

/* Do the mmap */
void *do_mmap (void *addr, size_t length, int writable, struct file *file, off_t offset) {
    struct file *mfile = file_reopen(file);

    void * ori_addr = addr;
    size_t read_bytes = length > file_length(file) ? file_length(file) : length;
    size_t zero_bytes = PGSIZE - read_bytes % PGSIZE;

    while (read_bytes > 0 || zero_bytes > 0) {
        size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
        size_t page_zero_bytes = PGSIZE - page_read_bytes;

        struct supplemental_page_table *spt = (struct supplemental_page_table*)malloc
                                        (sizeof(struct supplemental_page_table));
        spt->file = mfile;
        spt->offset = offset;
        spt->read_bytes = page_read_bytes;

        if (!vm_alloc_page_with_initializer (VM_FILE, addr, writable, lazy_load_segment, spt)) {
            return NULL;
        }
        read_bytes -= page_read_bytes;
        zero_bytes -= page_zero_bytes;
        addr       += PGSIZE;
        offset     += page_read_bytes;
    }
    return ori_addr;
}

/* Do the munmap */
void do_munmap (void *addr) {
    while (true) {
        struct page* page = spt_find_page(&thread_current()->spt, addr);
        
        if (page == NULL)
            break;

        struct supplemental_page_table * aux = (struct supplemental_page_table *) page->uninit.aux;
        
        // dirty(사용되었던) bit 체크
        if(pml4_is_dirty(thread_current()->pml4, page->va)) {
            file_write_at(aux->file, addr, aux->read_bytes, aux->offset);
            pml4_set_dirty (thread_current()->pml4, page->va, 0);
        }

        pml4_clear_page(thread_current()->pml4, page->va);
        addr += PGSIZE;
    }
}

Here is my Team git-repository For now, we've saved this git in an intact (error-free) state, but we'll create a state with the same errors and push it soon.

Thank you very much for your time!

1

There are 1 best solutions below

0
DJ Kim On

Resolved it!

The biggest problem that I didn't know what the problem was. After asking around people, I learned that the problem is called a "circular reference" and "duplicate header" issues. In short, these are problems that occur when objects reference each other, or when headers are compiled with duplicate headers. There's a lot of reference on the internet, so use this as a milestone.

This could be solved by inserting #pragma once or #ifndef HEADER_H #define HEADER_H #endif syntax into the header. In my case, I was able to solve it by inserting the latter case,#ifndef ..., and #ifdef into the header appropriately. I leave the answer to myself for anyone else who encounters the same problem in the future.

good luck guys!