From a12760fe9e0c9c226b4c59585090363f7b0beec8 Mon Sep 17 00:00:00 2001 From: "Guillermo J. Rozas" Date: Tue, 29 Oct 1991 22:35:01 +0000 Subject: [PATCH] Initial revision --- v7/src/microcode/bchdrn.c | 512 ++++++++++++++++++++++++++++++++++++++ v7/src/microcode/bchdrn.h | 181 ++++++++++++++ v7/src/microcode/bchutl.c | 107 ++++++++ 3 files changed, 800 insertions(+) create mode 100644 v7/src/microcode/bchdrn.c create mode 100644 v7/src/microcode/bchdrn.h create mode 100644 v7/src/microcode/bchutl.c diff --git a/v7/src/microcode/bchdrn.c b/v7/src/microcode/bchdrn.c new file mode 100644 index 000000000..335a7213f --- /dev/null +++ b/v7/src/microcode/bchdrn.c @@ -0,0 +1,512 @@ +/* -*- C -*- + +$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/bchdrn.c,v 1.1 1991/10/29 22:34:41 jinx Exp $ + +Copyright (c) 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and +Computer Science. Permission to copy this software, to redistribute +it, and to use it for any purpose is granted, subject to the following +restrictions and understandings. + +1. Any copy made of this software must include this copyright notice +in full. + +2. Users of this software agree to make their best efforts (a) to +return to the MIT Scheme project any improvements or extensions that +they make, so that these may be included in future releases; and (b) +to inform MIT of noteworthy uses of this software. + +3. All materials developed as a consequence of the use of this +software shall duly acknowledge such use, in accordance with the usual +standards of acknowledging credit in academic research. + +4. MIT has made no warrantee or representation that the operation of +this software will be error-free, and MIT is under no obligation to +provide any services, by way of maintenance, update, or otherwise. + +5. In conjunction with products arising from the use of this material, +there shall be no use of the name of the Massachusetts Institute of +Technology nor of any adaptation thereof in any advertising, +promotional, or sales literature without prior written consent from +MIT in each case. */ + +/* Drone program for overlapped I/O in bchscheme. */ + +#include +#include +#include +#include +#include "bchdrn.h" + +#define DEBUG + +extern char * EXFUN (error_name, (int)); +extern int EXFUN (retrying_file_operation, + (/* no prototype because (const char *) != (char *) */ + int (*)(), + int, char *, long, long, char *, char *, long *, + int (*)(char *, char *))); + +#ifdef HAVE_SYSV_SHARED_MEMORY + +static struct +{ + char * program_name; + char * file_name; /* gc file name */ + int shmid; /* shared memory descriptor */ + int tdron; /* total number of drones */ + int nbuf; /* total number of buffers */ + long bufsiz; /* size of each buffer in bytes */ + int sdron; /* index of first drone to start */ + int ndron; /* number of drones to start */ + int keep_p; /* keep the gc file if Scheme dies? */ +} arguments; + +struct argdesc +{ + char * name; + char * format; + PTR location; +}; + +static char string_a[] = "%s"; +#define STRING_FMT &string_a[0] + +static char decimal_int_a[] = "%d"; +#define DECIMAL_INT_FMT &decimal_int_a[0] + +static char decimal_long_a[] = "%ld"; +#define DECIMAL_LONG_FMT &decimal_long_a[0] + +static struct argdesc command_line[] = +{ + { "program_name", STRING_FMT, &arguments.program_name }, + { "file_name", STRING_FMT, &arguments.file_name }, + { "shmid", DECIMAL_INT_FMT, &arguments.shmid }, + { "tdron", DECIMAL_INT_FMT, &arguments.tdron }, + { "nbuf", DECIMAL_INT_FMT, &arguments.nbuf }, + { "bufsiz", DECIMAL_LONG_FMT, &arguments.bufsiz }, + { "sdron", DECIMAL_INT_FMT, &arguments.sdron }, + { "ndron", DECIMAL_INT_FMT, &arguments.ndron }, + { "keep_gc_file", DECIMAL_INT_FMT, &arguments.keep_p } +}; + +static int gc_fid = -1; +static char * shared_memory; +static struct buffer_info * gc_buffers; +static struct drone_info * myself; +static pid_t parent_pid, * wait_pid; +static jmp_buf abort_point; + +static void +DEFUN (shutdown, (sig), int sig) +{ + myself->state = drone_dead; + if (gc_fid != -1) + close (gc_fid); + shmdt (shared_memory); + if (sig == -1) + { + shmctl (arguments.shmid, IPC_RMID, ((struct shmid_ds *) 0)); + if (!arguments.keep_p) + unlink (arguments.file_name); + } + exit (0); + /*NOTREACHED*/ +} + +static void +DEFUN (abort_operation, (sig), int sig) +{ + signal (SIGQUIT, abort_operation); + myself->state = drone_aborting; + longjmp (abort_point, 1); + /*NOTREACHED*/ +} + +#if 0 +static void +DEFUN (handle_child_death, (sig), int sig) +{ + signal (SIGCHLD, handle_child_death); + (void) (wait ((int *) 0)); + return; +} +#endif + +static void +DEFUN (continue_running, (sig), int sig) +{ + signal (SIGCONT, continue_running); + return; +} + +static int +DEFUN (always_one, (operation_name, noise), + char * operation_name AND char * noise) +{ + return (1); +} + +static void +DEFUN (process_requests, (drone), struct drone_info * drone) +{ + extern int EXFUN (select, (int, int *, int *, int *, struct timeval *)); + long non_blocking_signal_mask, blocking_signal_mask, current_position = -1; + struct timeval timeout; + int result, count, buffer_index, flags; + pid_t read_pid; + + myself = drone; + drone->DRONE_PID = (getpid ()); + gc_fid = (open (arguments.file_name, O_RDWR, 0644)); + if (gc_fid == -1) + { + fprintf (stderr, + "%s (%d, process_requests): open failed. errno = %s.\n", + arguments.program_name, drone->index, (error_name (errno))); + fflush (stderr); + if (drone->DRONE_PPID == parent_pid) + (void) (kill (parent_pid, SIGCONT)); + shutdown (0); + /*NOTREACHED*/ + } +#ifdef DEBUG_1 + printf ("%s (%d, process_requests): Starting.\n", + arguments.program_name, drone->index); + fflush (stdout); +#endif + do + { + struct stat file_info; + + /* Force O_SYNC only if we are dealing with a raw device. */ + + if ((fstat (gc_fid, &file_info)) == -1) + { + fprintf (stderr, + "%s (%d, process_requests): fstat failed. errno = %s.\n", + arguments.program_name, drone->index, (error_name (errno))); + fflush (stderr); + } + else if ((file_info.st_mode & S_IFMT) != S_IFCHR) + break; + + if ((flags = (fcntl (gc_fid, F_GETFL, 0))) == -1) + { + fprintf + (stderr, + "%s (%d, process_requests): fcntl (F_GETFL) failed. errno = %s.\n", + arguments.program_name, drone->index, (error_name (errno))); + fflush (stderr); + } + else + { + flags |= O_SYNC; + if ((fcntl (gc_fid, F_SETFL, flags)) == -1) + { + fprintf + (stderr, + "%s (%d, process_requests): fcntl (F_SETFL) failed. errno = %s.\n", + arguments.program_name, drone->index, (error_name (errno))); + fflush (stderr); + } + } + } while (0); + + drone->state = drone_idle; +#ifdef DEBUG_1 + printf ("%s (%d, process_requests): PID = %d; PPID = %d.\n", + arguments.program_name, drone->index, drone->DRONE_PID, + drone->DRONE_PPID); + fflush (stdout); +#endif + if (drone->DRONE_PPID == parent_pid) + (void) (kill (parent_pid, SIGCONT)); + count = drone->index; + non_blocking_signal_mask = (sigblock (sigmask (SIGQUIT))); + blocking_signal_mask = (sigblock (sigmask (SIGQUIT))); + signal (SIGQUIT, abort_operation); + if (setjmp (abort_point)) + goto redo_dispatch; + + for (; 1; count++) + { + (void) (sigsetmask (non_blocking_signal_mask)); + timeout.tv_sec = 6; + timeout.tv_usec = 0; + result = (select (0, 0, 0, 0, &timeout)); + + if ((result == -1) && (errno == EINTR)) + { +redo_dispatch: + switch (drone->state) + { + default: + fprintf (stderr, + "\n%s (%d, process_requests): Unknown/bad operation %d.\n", + arguments.program_name, drone->index, drone->state); + fflush (stderr); + (void) (shutdown (0)); + /*NOTREACHED*/ + + case drone_idle: + continue; + + case drone_aborting: +#ifdef DEBUG_1 + printf ("\n%s (%d, process_requests): Aborting.", + arguments.program_name, drone->index); + fflush (stdout); +#endif + drone->buffer_index = -1; + current_position = -1; + break; + + case drone_reading: + case drone_writing: + { + /* Can't use buffer->bottom because the shared memory may be + attached at a different address! + */ + + int saved_errno; + char * operation_name, * buffer_address; + struct buffer_info * buffer; + struct gc_queue_entry * entry; + + buffer_index = (drone->buffer_index); + buffer = (gc_buffers + buffer_index); + + entry = ((struct gc_queue_entry *) + (((char *) drone) + (drone->entry_offset))); + entry->error_code = 0; + + operation_name = ((drone->state == drone_reading) + ? "read" + : "write"); + buffer_address = (shared_memory + (arguments.bufsiz * buffer_index)); +#ifdef DEBUG_1 + printf ("\n%s (%d, process_requests %s): Buffer index = %d", + arguments.program_name, drone->index, operation_name, + buffer_index); + printf ("\n\tBuffer address = 0x%lx; Position = 0x%lx; Size = 0x%lx.", + buffer_address, buffer->position, buffer->size); + fflush (stdout); +#endif + + result = (retrying_file_operation + (((drone->state == drone_reading) + ? ((int (*) ()) read) + : ((int (*) ()) write)), + gc_fid, buffer_address, + buffer->position, buffer->size, operation_name, NULL, + ¤t_position, always_one)); + + saved_errno = errno; + (void) (sigsetmask (blocking_signal_mask)); + + if (result == -1) + { + buffer->state = ((drone->state == drone_reading) + ? buffer_read_error + : buffer_write_error); + drone->buffer_index = -1; + entry->drone_index = -1; + entry->error_code = saved_errno; + entry->state = entry_error; + current_position = -1; +#ifdef DEBUG + printf ("\n%s (%d, process_requests): %s error (errno = %s).\n", + arguments.program_name, drone->index, operation_name, + (error_name (saved_errno))); + fflush (stdout); +#endif + } + else + { + buffer->state = ((drone->state == drone_reading) + ? buffer_ready + : buffer_idle); + drone->buffer_index = -1; + entry->drone_index = -1; + if (drone->state == drone_writing) + { + entry->retry_count = 0; + entry->state = entry_idle; + } +#ifdef DEBUG_1 + printf ("\n%s (%d, process_requests %s): Done.", + arguments.program_name, drone->index, operation_name); + fflush (stdout); +#endif + } + } + } + + drone->state = drone_idle; + read_pid = (*wait_pid); + if ((read_pid == parent_pid) || (read_pid == drone->DRONE_PID)) + (void) (kill (parent_pid, SIGCONT)); + count = 0; + } + else if ((result == 0) && (count == arguments.tdron)) + { + count = 0; + if ((kill (parent_pid, 0)) == -1) + (void) (shutdown (-1)); + } + } +} + +static void +DEFUN_VOID (start_drones) +{ + pid_t my_pid; + int counter, cpid; + long * drone_version; + struct drone_info *gc_drones, *drone; + + my_pid = (getpid ()); + shared_memory = (shmat (arguments.shmid, ATTACH_POINT, 0)); + if (shared_memory == ((char *) -1)) + { + fprintf (stderr, + "\ +%s (start_drones): Unable to attach shared memory segment %d (errno = %s).\n", + arguments.program_name, arguments.shmid, (error_name (errno))); + fflush (stderr); + exit (1); + } +#ifdef DEBUG_1 + printf ("%s (start_drones): Attached shared memory at address = 0x%lx.\n", + arguments.program_name, ((long) shared_memory)); + fflush (stdout); +#endif + signal (SIGINT, SIG_IGN); + signal (SIGQUIT, SIG_IGN); + signal (SIGHUP, shutdown); + signal (SIGTERM, shutdown); + signal (SIGCONT, continue_running); + gc_buffers = ((struct buffer_info *) + (shared_memory + (arguments.nbuf * arguments.bufsiz))); + gc_drones = ((struct drone_info *) (gc_buffers + arguments.nbuf)); + drone_version = ((long *) (gc_drones + arguments.tdron)); + wait_pid = ((pid_t *) (drone_version + 1)); + if (*drone_version != DRONE_VERSION_NUMBER) + { + fprintf (stderr, "%s (start_drones): stored drone version != drone version.\n", + arguments.program_name); + fprintf (stderr, "\t*drone_version = %d; DRONE_VERSION_NUMBER = %d.\n", + *drone_version, DRONE_VERSION_NUMBER); + fflush (stderr); + exit (1); + } + + for (counter = 1, drone = (gc_drones + (arguments.sdron + 1)); + counter < arguments.ndron; + counter++, drone ++) + { + if ((cpid = (fork ())) == 0) + { + drone->DRONE_PPID = my_pid; + process_requests (drone); + /*NOTREACHED*/ + } + else if (cpid == -1) + { + fprintf (stderr, + "%s (start_drones): fork failed; errno = %s.\n", + arguments.program_name, (error_name (errno))); + fflush (stderr); + } + } + drone = (gc_drones + arguments.sdron); + drone->DRONE_PPID = parent_pid; + if (arguments.ndron != 1) +#if 0 + signal (SIGCHLD, handle_child_death); +#else + signal (SIGCHLD, SIG_IGN); +#endif + process_requests (drone); + /*NOTREACHED*/ +} + +void +DEFUN (main, (argc, argv), int argc AND char ** argv) +{ + int count, nargs; + static char err_buf[1024]; +#if defined(DEBUG) || defined(DEBUG_1) + static char out_buf[1024]; + + setvbuf (stdout, &out_buf[0], _IOFBF, (sizeof (out_buf))); +#endif + setvbuf (stderr, &err_buf[0], _IOFBF, (sizeof (err_buf))); + +#ifdef DEBUG_1 + printf ("%s (main): Arguments =\n", argv[0]); + for (count = 1; count < argc; count++) + printf ("\t%s\n", argv[count]); + fflush (stdout); +#endif + + nargs = ((sizeof (command_line)) / (sizeof (struct argdesc))); + parent_pid = (getppid ()); + if (argc != nargs) + { + fprintf (stderr, + "%s (main): Wrong number of arguments (got %d, expected %d).\n", + argv[0], (argc - 1), (nargs - 1)); + fflush (stderr); + kill (parent_pid, SIGCONT); + exit (1); + } + for (count = 0; count < nargs; count++) + { + if (command_line[count].format == STRING_FMT) + (* ((char **) command_line[count].location)) = argv[count]; + else + sscanf (argv[count], + command_line[count].format, + command_line[count].location); + } + +#ifdef DEBUG_1 + printf ("%s (main): Parsed arguments =\n", argv[0]); + for (count = 0; count < nargs; count++) + { + if (command_line[count].format == STRING_FMT) + printf ("\t%s\t= %s\n", + command_line[count].name, + (* ((char **) (command_line[count].location)))); + else + printf ("\t%s\t= %d\n", + command_line[count].name, + (* ((int *) (command_line[count].location)))); + } + fflush (stdout); +#endif + + start_drones (); + exit (0); +} + +#define MAIN main + +#endif /* HAVE_SYSV_SHARED_MEMORY */ + +#ifndef MAIN + +void +DEFUN (main, (argc, argv), int argc AND char ** argv) +{ + fprintf (stderr, "%s: Not implemented.\n", (argv[0])); + fflush (stderr); + exit (1); +} + +#endif /* MAIN */ diff --git a/v7/src/microcode/bchdrn.h b/v7/src/microcode/bchdrn.h new file mode 100644 index 000000000..580520e8f --- /dev/null +++ b/v7/src/microcode/bchdrn.h @@ -0,0 +1,181 @@ +/* -*-C-*- + +$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/bchdrn.h,v 1.1 1991/10/29 22:34:20 jinx Exp $ + +Copyright (c) 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and +Computer Science. Permission to copy this software, to redistribute +it, and to use it for any purpose is granted, subject to the following +restrictions and understandings. + +1. Any copy made of this software must include this copyright notice +in full. + +2. Users of this software agree to make their best efforts (a) to +return to the MIT Scheme project any improvements or extensions that +they make, so that these may be included in future releases; and (b) +to inform MIT of noteworthy uses of this software. + +3. All materials developed as a consequence of the use of this +software shall duly acknowledge such use, in accordance with the usual +standards of acknowledging credit in academic research. + +4. MIT has made no warrantee or representation that the operation of +this software will be error-free, and MIT is under no obligation to +provide any services, by way of maintenance, update, or otherwise. + +5. In conjunction with products arising from the use of this material, +there shall be no use of the name of the Massachusetts Institute of +Technology nor of any adaptation thereof in any advertising, +promotional, or sales literature without prior written consent from +MIT in each case. */ + +/* Header file for overlapped I/O in bchscheme. */ + +#ifndef _BCHDRN_H_INCLUDED + +#define _BCHDRN_H_INCLUDED + +#include "ansidecl.h" +#ifdef _HPUX +# define HAVE_PREALLOC +# include +#endif +#ifdef _SUNOS4 +# include +#endif +#ifdef _ULTRIX +# include +#endif +#include + +/* #define AVOID_SYSV_SHARED_MEMORY */ + +#if defined(_HPUX) && !defined(AVOID_SYSV_SHARED_MEMORY) +# define HAVE_SYSV_SHARED_MEMORY + +# include +# if defined(SHL_MAGIC) +# define hpux8 1 +# endif + +/* Page tables can have no gaps in HP-UX < 8.0, leave a gap for malloc. */ + +# ifdef hp9000s300 +# ifdef hpux8 +# define ATTACH_POINT 0x60000000 +# else /* not hpux8 */ +# define MALLOC_SPACE (2 << 20) /* 2 Meg */ +# endif /* hpux8 */ +# endif /* hp9000s300 */ + +#endif /* _HPUX */ + +#if defined(_SUNOS4) && !defined(AVOID_SYSV_SHARED_MEMORY) +# define HAVE_SYSV_SHARED_MEMORY +#endif /* _SUNOS4 */ + +#if defined(_ULTRIX) && !defined(AVOID_SYSV_SHARED_MEMORY) +# define HAVE_SYSV_SHARED_MEMORY +#endif /* _ULTRIX */ + +#ifdef HAVE_SYSV_SHARED_MEMORY + +#define DRONE_VERSION_NUMBER ((1 << 16) | 1) + +#include +#include +#include +#include +#include +#include + +#ifndef MALLOC_SPACE +# define MALLOC_SPACE 0 +#endif + +#ifndef ATTACH_POINT +# define ATTACH_POINT 0 +#endif + +#define DRONE_EXTRA_T + +struct drone_extra_s +{ + pid_t my_pid; + pid_t my_ppid; +}; + +typedef struct drone_extra_s drone_extra_t; + +#define DRONE_PID drone_extra.my_pid +#define DRONE_PPID drone_extra.my_ppid + +#endif /* HAVE_SYSV_SHARED_MEMORY */ + +/* Shared definitions for all versions */ + +enum buffer_state +{ + buffer_idle, /* 0 */ + buffer_busy, /* 1, used for scan or free */ + buffer_ready, /* 2, after being read */ + buffer_queued, /* 3, never written, use as if read */ + buffer_being_read, /* 4 */ + buffer_read_error, /* 5 */ + buffer_being_written, /* 6 */ + buffer_write_error /* 7 */ +}; + +struct buffer_info +{ + int index; + enum buffer_state state; + long position; + long size; + PTR bottom; + PTR top; + PTR end; +}; + +enum drone_state +{ + drone_dead, /* 0 */ + drone_not_ready, /* 1 */ + drone_idle, /* 2 */ + drone_reading, /* 3 */ + drone_writing, /* 4 */ + drone_aborting /* 5 */ +}; + +struct drone_info +{ + int index; +#ifdef DRONE_EXTRA_T + drone_extra_t drone_extra; +#endif + enum drone_state state; + int buffer_index; + long entry_offset; +}; + +enum queue_entry_state +{ + entry_idle, /* 0 */ + entry_busy, /* 1 */ + entry_error /* 2 */ +}; + +struct gc_queue_entry +{ + int index; + enum queue_entry_state state; + struct buffer_info * buffer; + int drone_index; + int error_code; + int retry_count; +}; + +#endif /* _BCHDRN_H_INCLUDED */ diff --git a/v7/src/microcode/bchutl.c b/v7/src/microcode/bchutl.c new file mode 100644 index 000000000..d134d5833 --- /dev/null +++ b/v7/src/microcode/bchutl.c @@ -0,0 +1,107 @@ +/* -*-C-*- + +$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/bchutl.c,v 1.1 1991/10/29 22:35:01 jinx Exp $ + +Copyright (c) 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and +Computer Science. Permission to copy this software, to redistribute +it, and to use it for any purpose is granted, subject to the following +restrictions and understandings. + +1. Any copy made of this software must include this copyright notice +in full. + +2. Users of this software agree to make their best efforts (a) to +return to the MIT Scheme project any improvements or extensions that +they make, so that these may be included in future releases; and (b) +to inform MIT of noteworthy uses of this software. + +3. All materials developed as a consequence of the use of this +software shall duly acknowledge such use, in accordance with the usual +standards of acknowledging credit in academic research. + +4. MIT has made no warrantee or representation that the operation of +this software will be error-free, and MIT is under no obligation to +provide any services, by way of maintenance, update, or otherwise. + +5. In conjunction with products arising from the use of this material, +there shall be no use of the name of the Massachusetts Institute of +Technology nor of any adaptation thereof in any advertising, +promotional, or sales literature without prior written consent from +MIT in each case. */ + +#include +#include +#include "ansidecl.h" + +extern char * EXFUN (error_name, (int)); +extern int EXFUN (retrying_file_operation, + (int (*)(int, char *, unsigned int), + int, char *, long, long, char *, char *, long *, + int (*)(char *, char *))); + +char * +DEFUN (error_name, (code), int code) +{ + extern int sys_nerr; + extern char *sys_errlist[]; + static char buf[512]; + + if ((code >= 0) && (code <= sys_nerr)) + sprintf (&buf[0], "%d, %s", code, sys_errlist[code]); + else + sprintf (&buf[0], "%d, unknown error", code); + return (&buf[0]); +} + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +int +DEFUN (retrying_file_operation, + (operation, fid, ptr, position, nbytes, name, noise, curpos, abort_p), + int EXFUN ((*operation), (int, char *, unsigned int)) + AND int fid AND char * ptr AND long position AND long nbytes + AND char * name AND char * noise AND long * curpos + AND int EXFUN ((*abort_p), (char *, char *))) +{ + char * membuf = ptr; + long + bytes_to_transfer = nbytes, + bytes_transferred; + + if (*curpos != position) + while ((lseek (fid, position, SEEK_SET)) == -1) + if ((errno != EINTR) && ((*abort_p) ("lseek", noise))) + goto fail; + + while ((bytes_to_transfer > 0) + && ((bytes_transferred = + ((*operation) (fid, membuf, ((unsigned int) bytes_to_transfer)))) + != bytes_to_transfer)) + if (bytes_transferred == -1) + { + if ((errno != EINTR) && ((*abort_p) (name, noise))) + goto fail; + + while ((lseek (fid, (position + (nbytes - bytes_to_transfer)), SEEK_SET)) + == -1) + if ((errno != EINTR) && ((*abort_p) ("lseek", noise))) + goto fail; + } + else + { + bytes_to_transfer -= bytes_transferred; + membuf += bytes_transferred; + } + *curpos = (position + nbytes); + return (nbytes); + +fail: + *curpos = -1; + return (-1); +} + -- 2.25.1