*** 1.8 1993/08/10 20:46:44 --- changes 1993/08/16 23:11:16 *************** *** 1,6 **** --- 1,20 ---- Changes are listed in *reverse* order, most recent changes being first. + version 1.09 + + biosfs.c: + Implement file locking for BIOS devices. + dosmem.c: + Fix the Pexec(200,...) bug (trying to save the command line + image must be done *before* the existing program's memory + is freed). + nalloc2.c,util.c: + Allow kmalloc()'d memory to be returned to the OS, if possible. + xbios.c: + Dosound() can be called with a negative number as its parameter, + in which case it is only an inquiry function. + version 1.08 dosfile.c,dosdir.c,filesys.c: *** 1.8 1993/08/10 20:46:44 --- biosfs.c 1993/08/16 23:10:54 *************** *** 41,46 **** --- 41,47 ---- static long ARGS_ON_STACK bios_select P_((FILEPTR *f, long p, int mode)); static void ARGS_ON_STACK bios_unselect P_((FILEPTR *f, long p, int mode)); static long ARGS_ON_STACK bios_tseek P_((FILEPTR *f, long where, int whence)); + static long ARGS_ON_STACK bios_close P_((FILEPTR *f, int pid)); long ARGS_ON_STACK null_open P_((FILEPTR *f)); long ARGS_ON_STACK null_write P_((FILEPTR *f, const char *buf, long bytes)); *************** *** 63,69 **** DEVDRV bios_tdevice = { bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl, ! null_datime, null_close, bios_select, bios_unselect }; /* device driver for BIOS devices that are not terminals */ --- 64,70 ---- DEVDRV bios_tdevice = { bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl, ! null_datime, bios_close, bios_select, bios_unselect }; /* device driver for BIOS devices that are not terminals */ *************** *** 70,76 **** DEVDRV bios_ndevice = { null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl, ! null_datime, null_close, bios_select, bios_unselect }; DEVDRV null_device = { --- 71,77 ---- DEVDRV bios_ndevice = { null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl, ! null_datime, bios_close, bios_select, bios_unselect }; DEVDRV null_device = { *************** *** 117,122 **** --- 118,124 ---- ushort flags; /* flags for device open */ struct tty *tty; /* tty structure (if appropriate) */ struct bios_file *next; + short lockpid; /* owner of the lock */ }; struct bios_file BDEV[] = { *************** *** 1024,1029 **** --- 1026,1032 ---- char *aline; short dev; int i; + struct bios_file *b; if (mode == FIONREAD) { if (bconstat(f->fc.aux)) *************** *** 1175,1180 **** --- 1178,1218 ---- r = 0; } return r; + } else if (mode == F_SETLK || mode == F_SETLKW) { + struct flock *lck = (struct flock *)buf; + + b = (struct bios_file *)f->fc.index; + while (b->lockpid && b->lockpid != curproc->pid) { + if (mode == F_SETLKW && lck->l_type != F_UNLCK) + sleep(IO_Q, (long)b); + else + return ELOCKED; + } + if (lck->l_type == F_UNLCK) { + if (!(f->flags & O_LOCK)) { + DEBUG(("bios_ioctl: wrong file descriptor for UNLCK")); + return ENSLOCK; + } + if (b->lockpid != curproc->pid) + return ENSLOCK; + b->lockpid = 0; + f->flags &= ~O_LOCK; + wake(IO_Q, (long)b); /* wake anyone waiting for this lock */ + } else { + b->lockpid = curproc->pid; + f->flags |= O_LOCK; + } + } else if (mode == F_GETLK) { + struct flock *lck = (struct flock *)buf; + + b = (struct bios_file *)f->fc.index; + if (b->lockpid) { + lck->l_type = F_WRLCK; + lck->l_start = lck->l_len = 0; + lck->l_pid = b->lockpid; + } else { + lck->l_type = F_UNLCK; + } } else { /* Fcntl will automatically call tty_ioctl to handle * terminal calls that we didn't deal with *************** *** 1231,1236 **** --- 1269,1288 ---- else if (mode == O_WRONLY && tty->wsel == p) tty->wsel = 0; } + } + + static long ARGS_ON_STACK + bios_close(f, pid) + FILEPTR *f; + int pid; + { + struct bios_file *b; + + b = (struct bios_file *)f->fc.index; + if ((f->flags & O_LOCK) && (b->lockpid == pid)) { + b->lockpid = 0; + } + return 0; } /* *** 1.8 1993/08/10 20:46:44 --- debug.c 1993/08/13 18:41:26 *************** *** 608,616 **** out_device = 2; break; case 0x3f: /* F5: dump memory */ ! DUMPMEM(ker); ! DUMPMEM(core); ! DUMPMEM(alt); break; case 0x40: /* F6: dump processes */ DUMPPROC(); --- 608,617 ---- out_device = 2; break; case 0x3f: /* F5: dump memory */ ! DUMP_ALL_MEM(); ! break; ! case 0x58: /* shift+F5: dump kernel allocated memory */ ! NALLOC_DUMP(); break; case 0x40: /* F6: dump processes */ DUMPPROC(); *** 1.8 1993/08/10 20:46:44 --- dosmem.c 1993/08/16 18:28:26 *************** *** 543,548 **** --- 543,571 ---- } return mint_errno; } + + /* jr: add Pexec information to PROC struct */ + strncpy(p->cmdlin, b->p_cmdlin, 128); + p->fname[0] = 0; + if (mkload) { + char tmp[PATH_MAX]; + char *source = ptr1; + tmp[1] = ':'; + if (source[1] == ':') { + tmp[0] = source[0]; + source += 2; + } else + tmp[0] = 'A' + curproc->curdrv; + if (DIRSEP(source[0])) /* absolute path? */ + { + strncpy (&tmp[2], &source[0], PATH_MAX-2); + strcpy (p->fname, tmp); + } else { + if (! d_getcwd (&tmp[2], tmp[0] - 'A' + 1, PATH_MAX - 2)) + ksprintf (p->fname, "%s\\%s", tmp, source); + } + } + if (ptrace) p->ptracer = pid2proc(p->ppid); *************** *** 588,618 **** if (p->ptracer) p->ctxt[CURRENT].ptrace = 1; - /* jr: add Pexec information to PROC struct */ - p->cmdlin[0] = 0; - if (mkbase || mkload) - strncpy(p->cmdlin, ptr2, 128); - p->fname[0] = 0; - if (mkload) - { - char tmp[PATH_MAX]; - char *source = ptr1; - tmp[1] = ':'; - if (source[1] == ':') { - tmp[0] = source[0]; - source += 2; - } else - tmp[0] = 'A' + curproc->curdrv; - if (DIRSEP(source[0])) /* absolute path? */ - { - strncpy (&tmp[2], &source[0], PATH_MAX-2); - strcpy (p->fname, tmp); - } else { - if (! d_getcwd (&tmp[2], tmp[0] - 'A' + 1, PATH_MAX - 2)) - ksprintf (p->fname, "%s\\%s", tmp, source); - } - } - /* set the time/date stamp of u:\proc */ proctime = timestamp; procdate = datestamp; --- 611,616 ---- *************** *** 1137,1143 **** --- 1135,1144 ---- assert(p != curproc); /* take the child off both the global and ZOMBIE lists */ + { short sr = spl7(); rm_q(ZOMBIE_Q, p); + spl(sr); + } if (proclist == p) { proclist = p->gl_next; *** 1.8 1993/08/10 20:46:44 --- mem.c 1993/08/13 18:11:30 *************** *** 33,46 **** */ /* initial number of memory regions */ ! #define NREGIONS 512 /* number of new regions to allocate when the initial ones are used up */ ! #define NEWREGIONS 256 static MEMREGION use_regions[NREGIONS+1]; MEMREGION *rfreelist; /* these variables are set in init_core(), and used in * init_mem() */ --- 33,51 ---- */ /* initial number of memory regions */ ! #define NREGIONS ((8*1024)/sizeof(MEMREGION)) /* number of new regions to allocate when the initial ones are used up */ ! #define NEWREGIONS ((8*1024)/sizeof(MEMREGION)) static MEMREGION use_regions[NREGIONS+1]; MEMREGION *rfreelist; + /* variable for debugging purposes; number of times we've needed + * to get new regions + */ + int num_reg_requests = 0; + /* these variables are set in init_core(), and used in * init_mem() */ *************** *** 342,347 **** --- 347,353 ---- newstuff = get_region(core, NEWREGIONS*SIZEOF(MEMREGION), PROT_S); newfrees = newstuff ? (MEMREGION *)newstuff->loc : 0; if (newfrees) { + num_reg_requests++; newfrees[NEWREGIONS-1].next = 0; newfrees[NEWREGIONS-1].links = 0; for (i = 0; i < NEWREGIONS-1; i++) { *************** *** 1609,1617 **** --- 1615,1626 ---- void DUMP_ALL_MEM() { + #ifdef DEBUG_INFO DUMPMEM(ker); DUMPMEM(core); DUMPMEM(alt); + FORCE("new memory region descriptor pages: %d", num_reg_requests); + #endif } void *** 1.8 1993/08/10 20:46:44 --- nalloc2.c 1993/08/13 20:36:48 *************** *** 1,5 **** /* ! * Copyright 1992 Atari Corporation. All rights reserved. */ /* --- 1,6 ---- /* ! * Copyright 1992,1993 Atari Corporation. ! * All rights reserved. */ /* *************** *** 65,75 **** void *start; long len; { ! struct arena *a = start; struct block *b; ! a->a_next = a_first; ! a_first = a; a->a_ffirst = b = (struct block *)(a+1); a->a_size = len; b->b_next = NULL; --- 66,82 ---- void *start; long len; { ! struct arena *a; struct block *b; ! for (a = a_first; a && a->a_next; a = a->a_next) ! continue; ! if (a) ! a->a_next = (struct arena *)start; ! else ! a_first = (struct arena *)start; ! a = start; ! a->a_next = NULL; a->a_ffirst = b = (struct block *)(a+1); a->a_size = len; b->b_next = NULL; *************** *** 230,244 **** fb->b_next = b->b_next; } - #if 0 /* if, after coalescing, this arena is entirely free, Mfree it! */ ! if (a->a_ffirst == a+1 && (a->a_ffirst->b_size + sizeof(struct block)) == a->a_size) { NALLOC_DEBUG('!'); *qa = a->a_next; (void)Mfree(a); - } #endif return; } --- 237,253 ---- fb->b_next = b->b_next; } /* if, after coalescing, this arena is entirely free, Mfree it! */ ! if ((struct arena *)a->a_ffirst == a+1 && (a->a_ffirst->b_size + sizeof(struct block)) == a->a_size) { NALLOC_DEBUG('!'); *qa = a->a_next; + #if 1 + kfree(a); /* MiNT -- give back so it can be used by users */ + #else (void)Mfree(a); #endif + } return; } *** 1.8 1993/08/10 20:46:44 --- proc.c 1993/08/13 22:46:50 *************** *** 1,6 **** /* Copyright 1990,1991,1992 Eric R. Smith. ! Copyright 1992 Atari Corporation. All rights reserved. */ --- 1,6 ---- /* Copyright 1990,1991,1992 Eric R. Smith. ! Copyright 1992,1993 Atari Corporation. All rights reserved. */ *** 1.8 1993/08/10 20:46:44 --- procfs.c 1993/08/13 22:49:58 *************** *** 553,558 **** --- 553,559 ---- { PROC *p; extern long mcpu; /* in main.c */ + short sr; p = (PROC *)f->devinfo; switch(mode) { *************** *** 654,661 **** --- 655,664 ---- TRACE(("PTRACEGO: no signal")); } /* wake the process up */ + sr = spl7(); rm_q(p->wait_q, p); add_q(READY_Q, p); + spl(sr); return 0; /* jr: PLOADINFO returns information about params passed to Pexec */ case PLOADINFO: *** 1.8 1993/08/10 20:46:44 --- util.c 1993/08/13 19:00:52 *************** *** 1,6 **** /* Copyright 1990,1991,1992 Eric R. Smith. ! Copyright 1992 Atari Corporation. All rights reserved. */ --- 1,6 ---- /* Copyright 1990,1991,1992 Eric R. Smith. ! Copyright 1992,1993 Atari Corporation. All rights reserved. */ *************** *** 107,113 **** * kernel memory allocation routines */ ! #define KERMEM_THRESHOLD QUANTUM-8 #define KMAGIC ((MEMREGION *)0x87654321L) #define NKMAGIC 0x19870425L --- 107,118 ---- * kernel memory allocation routines */ ! #define KERMEM_THRESHOLD (QUANTUM-8) ! #if 0 ! #define KERMEM_SIZE QUANTUM ! #else ! #define KERMEM_SIZE ((KERMEM_THRESHOLD+8)*2) ! #endif #define KMAGIC ((MEMREGION *)0x87654321L) #define NKMAGIC 0x19870425L *************** *** 142,154 **** DEBUG(("kmalloc(%lx): nalloc is out of memory",size)); /* If this is commented out, then we fall through to try_getregion */ ! if (0 == (m = get_region(alt, QUANTUM, PROT_S))) { ! if (0 == (m = get_region(core, QUANTUM, PROT_S))) { DEBUG(("No memory for another arena")); goto try_getregion; } } ! nalloc_arena_add((void *)m->loc,QUANTUM); goto tryagain; } } --- 147,162 ---- DEBUG(("kmalloc(%lx): nalloc is out of memory",size)); /* If this is commented out, then we fall through to try_getregion */ ! if (0 == (m = get_region(alt, KERMEM_SIZE, PROT_S))) { ! if (0 == (m = get_region(core, KERMEM_SIZE, PROT_S))) { DEBUG(("No memory for another arena")); goto try_getregion; } } ! lp = (long *)m->loc; ! *lp++ = (long)KMAGIC; ! *lp++ = (long)m; ! nalloc_arena_add((void *)lp,KERMEM_SIZE); goto tryagain; } } *** 1.8 1993/08/10 20:46:44 --- xbios.c 1993/08/12 21:38:22 *************** *** 29,35 **** * unexpectedly. So we play some dirty tricks here: the function * call is treated like a signal handler, and we take advantage * of the fact that no context switches will take place while ! * in supervisor mode. ASSUMPTION: the user will not choose to * switch back to user mode, or if s/he does it will be as part * of a longjmp(). * --- 29,35 ---- * unexpectedly. So we play some dirty tricks here: the function * call is treated like a signal handler, and we take advantage * of the fact that no context switches will take place while ! * in supervisor mode. ASSTMPTION: the user will not choose to * switch back to user mode, or if s/he does it will be as part * of a longjmp(). * *************** *** 266,272 **** { MEMREGION *r; ! if (!no_mem_prot) { /* check that this process has access to the memory */ /* (if not, the next line will cause a bus error) */ (void)(*((volatile char *)ptr)); --- 266,272 ---- { MEMREGION *r; ! if (!no_mem_prot && ((long)ptr >= 0)) { /* check that this process has access to the memory */ /* (if not, the next line will cause a bus error) */ (void)(*((volatile char *)ptr)); *************** *** 281,288 **** } } ! Dosound(ptr); ! return 0; } void --- 281,287 ---- } } ! return call_dosound(ptr); } void *** 1.8 1993/08/10 20:46:44 --- sproto.h 1993/08/12 21:41:30 *************** *** 33,38 **** --- 33,39 ---- /* syscall.s */ char * ARGS_ON_STACK lineA0 P_((void)); void ARGS_ON_STACK call_aes P_((short **)); + long ARGS_ON_STACK call_dosound P_((const void *)); long ARGS_ON_STACK callout P_((long, ...)); long ARGS_ON_STACK callout1 P_((long, int)); long ARGS_ON_STACK callout2 P_((long, int, int)); *** 1.8 1993/08/10 20:46:44 --- version.h 1993/08/12 21:20:36 *************** *** 1,5 **** #define MAJ_VERSION 1 ! #define MIN_VERSION 8 #ifndef MULTITOS #define BETA --- 1,5 ---- #define MAJ_VERSION 1 ! #define MIN_VERSION 9 #ifndef MULTITOS #define BETA