/* * Reallocate the maps for a process * * Subtlety: On a 32K box we have the udata area being copied to/from * the stash. As we always realloc for the live process we don't have * to worry about this in the 32K + common case because we'll switchin * at one size, and switchout at the other and the udata will just get * saved/restored to the right places. */ int pagemap_realloc(uint16_t size) { int have = maps_needed(udata.u_top); int want = maps_needed(size); uint8_t *ptr = (uint8_t *) & udata.u_page; /* If we are shrinking then free pages and propogate the common page into the freed spaces */ if (want == have) return 0; if (have > want) { pfree[pfptr++] = ptr[1]; udata.u_ptab->p_page = udata.u_page; return 0; } /* If we are adding then just insert the new pages, keeping the common unchanged at the top */ if (want - have > pfptr) return ENOMEM; /* We don't want to take an interrupt here while our page mappings are incomplete. We may restore bogus mappings and then take a second IRQ into hyperspace */ __critical { ptr[0] = pfree[--pfptr]; /* Copy the updated allocation into the ptab */ udata.u_ptab->p_page = udata.u_page; /* Now fix the vectors up - they've potentially teleported up to 32K up the user address space, we need to put a copy back in low memory before we switch to this memory map */ program_vectors(&udata.u_page); } return 0; }
/* * Reallocate the maps for a process */ int pagemap_realloc(usize_t size) { int8_t have = maps_needed(udata.u_top); int8_t want = maps_needed(size); uint8_t *ptr = (uint8_t *) & udata.u_page; int8_t i; uint8_t update = 0; irqflags_t irq; /* If we are shrinking then free pages and propogate the common page into the freed spaces */ if (want == have) return 0; /* We don't want to take an interrupt here while our page mappings are incomplete. We may restore bogus mappings and then take a second IRQ into hyperspace */ irq = di(); if (have > want) { for (i = want; i < have; i++) { pfree[pfptr++] = ptr[i - 1]; ptr[i - 1] = ptr[3]; } /* We collapsed top and bottom, so we need to sort our vectors and common space out */ if (want == 1) update = 1; } else if (want - have <= pfptr) { /* If we are adding then just insert the new pages, keeping the common unchanged at the top */ for (i = have; i < want; i++) ptr[i - 1] = pfree[--pfptr]; update = 1; } else { irqrestore(irq); return ENOMEM; } /* Copy the updated allocation into the ptab */ udata.u_ptab->p_page = udata.u_page; udata.u_ptab->p_page2 = udata.u_page2; /* Now fix the vectors up - they've potentially teleported up to 48K up the user address space, we need to put a copy back in low memory before we switch to this memory map */ if (update) program_vectors(&udata.u_page); irqrestore(irq); return 0; }
/* Newproc fixes up the tables for the child of a fork but also for init * Call in the processes context! * This process MUST be run immediately (since it sets status P_RUNNING) */ void newproc(ptptr p) { /* Passed New process table entry */ uint8_t *j; irqflags_t irq; irq = di(); /* Note that ptab_alloc clears most of the entry */ /* calculate base page of process based on ptab table offset */ udata.u_page = p->p_page; udata.u_page2 = p->p_page2; program_vectors(&p->p_page); /* set up vectors in new process and if needed copy any common code */ p->p_status = P_RUNNING; nready++; /* runnable process count */ p->p_pptr = udata.u_ptab; p->p_ignored = udata.u_ptab->p_ignored; p->p_tty = udata.u_ptab->p_tty; p->p_uid = udata.u_ptab->p_uid; /* Set default priority */ p->p_priority = MAXTICKS; /* For systems where udata is actually a pointer or a register object */ #ifdef udata p->p_udata = &udata; #endif udata.u_ptab = p; memset(&udata.u_utime, 0, 4 * sizeof(clock_t)); /* Clear tick counters */ rdtime32(&udata.u_time); if (udata.u_cwd) i_ref(udata.u_cwd); if (udata.u_root) i_ref(udata.u_root); udata.u_cursig = 0; udata.u_error = 0; for (j = udata.u_files; j < (udata.u_files + UFTSIZE); ++j) { if (*j != NO_FILE) ++of_tab[*j].o_refs; } irqrestore(irq); }