2015-06-09 2 views
3

В Minix 3.1.2a У меня есть структура «struct proc», где хранится PCB любого процесса, , но у меня проблема при добавлении нового атрибута "p_currenthash" в приведенном ниже коде. Я не могу изменить его значение, за исключением использования константы, определенной директивой #define; в противном случае система перестает отвечать. Для наглядности здесь есть структура:В C не удается изменить атрибут struct, за исключением использования #define val

struct proc { 
    struct stackframe_s p_reg; /* process' registers saved in stack frame */ 

#if (CHIP == INTEL) 
    reg_t p_ldt_sel;  /* selector in gdt with ldt base and limit */ 
    struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */ 
#endif 

#if (CHIP == M68000) 
/* M68000 specific registers and FPU details go here. */ 
#endif 

    proc_nr_t p_nr;  /* number of this process (for fast access) */ 
    struct priv *p_priv;  /* system privileges structure */ 
    short p_rts_flags;  /* process is runnable only if zero */ 
    short p_misc_flags;  /* flags that do suspend the process */ 

    char p_priority;  /* current scheduling priority */ 
    char p_max_priority;  /* maximum scheduling priority */ 
    char p_ticks_left;  /* number of scheduling ticks left */ 
    char p_quantum_size;  /* quantum size in ticks */ 

    struct mem_map p_memmap[NR_LOCAL_SEGS]; /* memory map (T, D, S) */ 

    clock_t p_user_time;  /* user time in ticks */ 
    clock_t p_sys_time;  /* sys time in ticks */ 

    struct proc *p_nextready; /* pointer to next ready process */ 
    struct proc *p_caller_q; /* head of list of procs wishing to send */ 
    struct proc *p_q_link; /* link to next proc wishing to send */ 
    message *p_messbuf;  /* pointer to passed message buffer */ 
    int p_getfrom_e;  /* from whom does process want to receive? */ 
    int p_sendto_e;  /* to whom does process want to send? */ 

    sigset_t p_pending;  /* bit map for pending kernel signals */ 



    char p_name[P_NAME_LEN]; /* name of the process, including \0 */ 

    int p_endpoint;  /* endpoint number, generation-aware */ 

#if DEBUG_SCHED_CHECK 
    int p_ready, p_found; 
#endif 

    char p_currenthash; /* hash */ 

}; 

Теперь предположим, что хочу установить его значение. Первоначально я использую константу, определенную ниже.

#define NONE -1 

register struct proc *rp; 

rp->p_currenthash=NONE; 

Это работает отлично, но это: rp->p_currenthash=0 ; заставит программу перестать отвечать на запросы.

Любые предложения будут оценены

Вот основной инициализации в main():

/* Start the ball rolling. */ 
    struct boot_image *ip; /* boot image pointer */ 
    register struct proc *rp; /* process pointer */ 
    register struct priv *sp; /* privilege structure pointer */ 
    register int i, s; 
    int hdrindex;   /* index to array of a.out headers */ 
    phys_clicks text_base; 
    vir_clicks text_clicks, data_clicks; 
    reg_t ktsb;   /* kernel task stack base */ 
    struct exec e_hdr;  /* for a copy of an a.out header */ 

    /* Initialize the interrupt controller. */ 
    intr_init(1); 

    /* Clear the process table. Anounce each slot as empty and set up mappings 
    * for proc_addr() and proc_nr() macros. Do the same for the table with 
    * privilege structures for the system processes. 
    */ 
    for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) { 
    rp->p_rts_flags = SLOT_FREE;  /* initialize free slot */ 
    rp->p_nr = i;    /* proc number from ptr */ 

    rp->p_currenthash=NONE; 

    rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */ 

     (pproc_addr + NR_TASKS)[i] = rp;  /* proc ptr from number */ 
    } 
    for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) { 
    sp->s_proc_nr = NONE;   /* initialize as free */ 
    sp->s_id = i;    /* priv structure index */ 
    ppriv_addr[i] = sp;   /* priv ptr from number */ 
    } 

    /* Set up proc table entries for processes in boot image. The stacks of the 
    * kernel tasks are initialized to an array in data space. The stacks 
    * of the servers have been added to the data segment by the monitor, so 
    * the stack pointer is set to the end of the data segment. All the 
    * processes are in low memory on the 8086. On the 386 only the kernel 
    * is in low memory, the rest is loaded in extended memory. 
    */ 

    /* Task stacks. */ 
    ktsb = (reg_t) t_stack; 

    for (i=0; i < NR_BOOT_PROCS; ++i) { 
    ip = &image[i];    /* process' attributes */ 
    rp = proc_addr(ip->proc_nr);  /* get process pointer */ 
    ip->endpoint = rp->p_endpoint;  /* ipc endpoint */ 
    rp->p_max_priority = ip->priority; /* max scheduling priority */ 
    rp->p_priority = ip->priority;  /* current priority */ 
    rp->p_quantum_size = ip->quantum; /* quantum size in ticks */ 
    rp->p_ticks_left = ip->quantum;  /* current credit */ 
    strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */ 
    (void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */ 
    priv(rp)->s_flags = ip->flags;   /* process flags */ 
    priv(rp)->s_trap_mask = ip->trap_mask;  /* allowed traps */ 
    priv(rp)->s_call_mask = ip->call_mask;  /* kernel call mask */ 
    priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */ 
    if (iskerneln(proc_nr(rp))) {  /* part of the kernel? */ 
     if (ip->stksize > 0) {  /* HARDWARE stack size is 0 */ 
      rp->p_priv->s_stack_guard = (reg_t *) ktsb; 
      *rp->p_priv->s_stack_guard = STACK_GUARD; 
     } 
     ktsb += ip->stksize; /* point to high end of stack */ 
     rp->p_reg.sp = ktsb; /* this task's initial stack ptr */ 
     text_base = kinfo.code_base >> CLICK_SHIFT; 
        /* processes that are in the kernel */ 
     hdrindex = 0;  /* all use the first a.out header */ 
    } else { 
     hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */ 
    } 

    /* The bootstrap loader created an array of the a.out headers at 
    * absolute address 'aout'. Get one element to e_hdr. 
    */ 
    phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr), 
         (phys_bytes) A_MINHDR); 
    /* Convert addresses to clicks and build process memory map */ 
    text_base = e_hdr.a_syms >> CLICK_SHIFT; 
    text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT; 
    if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0;  /* common I&D */ 
    data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT; 
    rp->p_memmap[T].mem_phys = text_base; 
    rp->p_memmap[T].mem_len = text_clicks; 
    rp->p_memmap[D].mem_phys = text_base + text_clicks; 
    rp->p_memmap[D].mem_len = data_clicks; 
    rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks; 
    rp->p_memmap[S].mem_vir = data_clicks; /* empty - stack is in data */ 

    /* Set initial register values. The processor status word for tasks 
    * is different from that of other processes because tasks can 
    * access I/O; this is not allowed to less-privileged processes 
    */ 
    rp->p_reg.pc = (reg_t) ip->initial_pc; 
    rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW; 

    /* Initialize the server stack pointer. Take it down one word 
    * to give crtso.s something to use as "argc". 
    */ 
    if (isusern(proc_nr(rp))) {  /* user-space process? */ 
     rp->p_reg.sp = (rp->p_memmap[S].mem_vir + 
       rp->p_memmap[S].mem_len) << CLICK_SHIFT; 
     rp->p_reg.sp -= sizeof(reg_t); 
    } 

    /* Set ready. The HARDWARE task is never ready. */ 
    if (rp->p_nr != HARDWARE) { 
     rp->p_rts_flags = 0;  /* runnable if no flags */ 
     lock_enqueue(rp);  /* add to scheduling queues */ 
    } else { 
     rp->p_rts_flags = NO_MAP; /* prevent from running */ 
    } 

    /* Code and data segments must be allocated in protected mode. */ 
    alloc_segments(rp); 
    } 
+4

Imho это связано с использованием поля currenthash, а не его инициализации. Используется ли какое-либо значение (включая 0) с помощью макроса «NONE»? –

+4

Убедитесь, что вы полностью перекомпилируете! Если в некоторых файлах кода используется старое определение 'struct proc', вы можете перезаписать другие переменные. –

+0

Не хватает информации. Показать код, ответственный за инициализацию 'rp' и контекста использования. Кроме того, где размещается определение этой структуры? Если он находится в файле '.cpp', вам нужно выполнить полную перестройку. –

ответ

0

acutually проблема не решена, сначала «p_currenthash» инициализируется в основном, как показано выше, в дальнейшем в функции называется pic_proc, я имею этот код:

register struct proc **xpp;   /* iterate over queue */ 
    register struct proc *rp;   /* process to run */ 
    int q; 
    for (q=0; q < NR_SCHED_QUEUES; q++) 
     { 
     if ((rp = rdy_head[q]) != NIL_PROC) 
     { 
     for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready) 
      { 
       if ((*xpp)->p_currenthash==NONE) 
        { 
         pick_val++;  

        } 
      } 
     } 
    } 

, что код работает отлично, не внутри, если если я изменил а, ttribute "p_currenthash" проблема ocuured, как показано ниже:

register struct proc **xpp;   /* iterate over queue */ 
    register struct proc *rp;   /* process to run */ 
    int q; 
    for (q=0; q < NR_SCHED_QUEUES; q++) 
     { 
     if ((rp = rdy_head[q]) != NIL_PROC) 
     { 
     for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready) 
      { 
       if ((*xpp)->p_currenthash==NONE) 
        { 
         pick_val++;  
         (*xpp)->p_currenthash=1; 
        } 
      } 
     } 
    } 

я действительно не могу понять проблему.

1
register struct proc *rp; 

rp->p_currenthash=NONE; 

rp - неинициализированный указатель; он не указывает на действительный объект struct proc, и поэтому разыменование его приводит к неопределенным поведением. Тот факт, что это не сработало при присвоении -1, было чистой удачей. (неудача, потому что она вводит вас в заблуждение, чтобы вы считали, что делаете что-то значимое)

+0

' rp' представляется здесь инициализированным: 'for (rp = BEG_PROC_ADDR, ...' – tangrs

+0

фактически инициализируется в основном, если вы проверяете код previouse, а также функцию do_fork, также если не инициализировали его ' не пройдем условие для цикла (! = NIL_PROC), и оно не будет учитываться в «pick_val», но оно подсчитывается. – user2963216