Operating Systems 3rd Edition Nutt Solutions Manual

bardhdinci22 10 views 56 slides Apr 19, 2025
Slide 1
Slide 1 of 56
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56

About This Presentation

Operating Systems 3rd Edition Nutt Solutions Manual
Operating Systems 3rd Edition Nutt Solutions Manual
Operating Systems 3rd Edition Nutt Solutions Manual


Slide Content

Operating Systems 3rd Edition Nutt Solutions
Manual install download
https://testbankfan.com/product/operating-systems-3rd-edition-
nutt-solutions-manual/
Download more testbank from https://testbankfan.com

We believe these products will be a great fit for you. Click
the link to download now, or visit testbankfan.com
to discover even more!
Operating Systems 3rd Edition Nutt Test Bank
https://testbankfan.com/product/operating-systems-3rd-edition-
nutt-test-bank/
Operating Systems 3rd Edition Deitel Solutions Manual
https://testbankfan.com/product/operating-systems-3rd-edition-
deitel-solutions-manual/
Operating Systems Design And Implementation 3rd Edition
Tanenbaum Solutions Manual
https://testbankfan.com/product/operating-systems-design-and-
implementation-3rd-edition-tanenbaum-solutions-manual/
Understanding Operating Systems 7th Edition McHoes
Solutions Manual
https://testbankfan.com/product/understanding-operating-
systems-7th-edition-mchoes-solutions-manual/

Understanding Operating Systems 8th Edition McHoes
Solutions Manual
https://testbankfan.com/product/understanding-operating-
systems-8th-edition-mchoes-solutions-manual/
Modern Operating Systems 4th Edition Tanenbaum
Solutions Manual
https://testbankfan.com/product/modern-operating-systems-4th-
edition-tanenbaum-solutions-manual/
Understanding Operating Systems 5th Edition McHoes
Solutions Manual
https://testbankfan.com/product/understanding-operating-
systems-5th-edition-mchoes-solutions-manual/
Survey of Operating Systems 5th Edition Holcombe
Solutions Manual
https://testbankfan.com/product/survey-of-operating-systems-5th-
edition-holcombe-solutions-manual/
Operating Systems Internals and Design Principles 9th
Edition Stallings Solutions Manual
https://testbankfan.com/product/operating-systems-internals-and-
design-principles-9th-edition-stallings-solutions-manual/

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
Chapter 9: High-Level Synchronization and Interprocess
Communication
Exercises
1. Here is one solution. Another one uses the monitor to encapsulate the resources rather
than just the entry and exit.
monitor sharedV {
public enter(int i) {set i busy;};
public exit(int i) {set i idle;};
};

p_0() {
...
enter(2);
access V_2;
exit(2)
...
}

p_1() {
...
enter(0);
access V_0
exit(0)
...
enter(2);
access V_2;
exit(2)
...
enter(0);
enter(2);
access V_0
access V_2;
exit(0)
exit(2)
}

p_2() {
...
enter(0);
access V_0
exit(0)
...
enter(1);
access V_1;
exit(1)
...
enter(0);
enter(1);
access V_0
access V_1;
exit(0)

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
exit(1)
}

p_3() {
...
enter(1);
access V_1;
exit(1)
...
}
2. Here is one solution.
semaphore s0 = 1, s1 = 1, s2 = 1;
...
P_simultaneous(...);
V_simultaneous(...);

p_0() {
...
P_simultaneous(s0, s1);
access V_0 & V_1;
V_simultaneous(s0, s1);
...
}

p_1() {
...
P_simultaneous(s1, s2);
access V_1 & V_2;
V_simultaneous(s0, s1);
...
}

p_2() {
...
P_simultaneous(s0, s2);
access V_0 & V_2;
V_simultaneous(s0, s1);
...
}
3. Here is one solution.
monitor semaphore {
private:
int count = 1; /* set to the initial value of the semaphore
*/
condition hold;
public:
P() {count--; if(count <= 0) hold.wait;};
V() {count++; hold.signal:};
};

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
4. Condition variables are just signaling semaphores (such as the full/empty semaphores
in the bounded buffer problem). The solution to this problem requires that you know
how mutual exclusion is implemented in the monitor. Then the condition variable
wait code must enqueue the thread and release the mutual exclusion. Similarly, the
signal code obtains mutually exclusive access to the monitor and dequeues a thread.
You will need to provide some guidance as to the amount of detail you want as an
acceptable solution to this problem. Here is some pseudo code (that has only been
debugged “by eye”):
struct monitor_t {
private:
semaphore mutex = 1;
int cv = 0;
<ADT data structures>
...
public:
proc_i(...) {
P(mutex);
<processing for proc_i>
/* CV wait */
cv--;
while(cv < 0) {
enqueue(self, cv_list);
setState(self, blocked);
V(mutex);
yield(); /* Call the scheduler */
P(mutex);
}
/* CV signal */
cv++;
if(cv <= 0) {
pid = dequeue(cv_list);
setState(pid, ready);
V(mutex);
yield(); /* Call the scheduler */
P(mutex);
}
V(mutex);
};
...
};
5. The idea is to translate the solution for #4 into System V semaphores:
struct monitor_t {
private:
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} arg;
arg.val = 1; /* Initial value of semaphore */
int mutex;
struct sembuf opns[1];

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
int cv = 0; /* You could use an event here, but it will be
* tricky releasing the mutex
*/
<ADT data structures>
...
public:
monitor_t() {
mutex = semget(MY_MONITOR, 1, 0666|IPC_CREATE);
if(mutex < 0)
{
fprintf(stderr, "Semaphore not available \n");
exit(0);
}
if(semctl(id, 0, SETVAL, arg) < 0)
{
fprintf( stderr, "Unable to set semaphore value \n");
}
/* Set up the sembuf structure. */
opns[0].sem_num = 0;
opns[0].sem_flg = 0;
};
proc_i(...) {
/* P(mutex) */
opns[0].sem_op = -1;
semop(id, opns, 1);
<processing for proc_i>
/* CV wait */
cv--;
while(cv < 0) {
enqueue(self, cv_list);
setState(self, blocked);
/* V(mutex) */
opns[0].sem_op = 1;
semop(id, opns, 1);
yield(); /* Call the scheduler */
/* P(mutex) */
opns[0].sem_op = -1;
semop(id, opns, 1);
}
/* CV signal */
cv++;
if(cv <= 0) {
pid = dequeue(cv_list);
setState(pid, ready);
/* V(mutex) */
opns[0].sem_op = 1;
semop(id, opns, 1);
yield(); /* Call the scheduler */
/* P(mutex) */
opns[0].sem_op = -1;
semop(id, opns, 1);
}
/* V(mutex) */
opns[0].sem_op = 1;
semop(id, opns, 1);
};
...

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
};
6. Here is the basic idea of a solution:
struct monitor_t {
private:
HANDLE mutex;
Char *mName = “mutexName”;
int cv = 0;
<ADT data structures>
...
public:
monitor_t() {
mutex = CreateMutex(NULL, FALSE, mName);
};
proc_i(...) {
WaitForSingleObject(mutex, INFINITE); /* P(mutex */
<processing for proc_i>
/* CV wait */
cv--;
while(cv < 0) {
enqueue(self, cv_list);
setState(self, blocked);
ReleaseMutex(mutex); /* V(mutex) */
yield(); /* Call the scheduler */
WaitForSingleObject(mutex, INFINITE); /* P(mutex) */
}
/* CV signal */
cv++;
if(cv <= 0) {
pid = dequeue(cv_list);
setState(pid, ready);
ReleaseMutex(mutex); /* V(mutex) */
yield(); /* Call the scheduler */
WaitForSingleObject(mutex, INFINITE); /* P(mutex) */
}
ReleaseMutex(mutex); /* V(mutex) */
};
...
};
7. Here is one solution.
monitor sleepy_barber {
private:
int number_of_customers = 0;
condition_variable haircut, sleepy;

public:
request_haircut {
number_of_customers = number_of_customers + 1;
if (number_of_customers == 1) sleepy.signal;
haircut.wait;

}

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»

take_customer {
if (number_of_customers == 0) sleepy.wait;
number_of_customers = number_of_customers - 1;
haircut.signal;
}

}

The barber is a cyclic process of the form:
while (TRUE) {
sleepy_barber.take_customer;
cut_hair
}

Each customer has the form:
...
sleepy_barber.request_haircut
get_haircut;
...
8. An asynchronous send operation can be used in any situation in which the sending
process wishes to transmit information to a sender, but it does not care when the
message is received. In the SOR example, the central process can assign work to an
equation solver using an asynchronous send. (The centralized process will ultimately
have to synchronize the completion of the equation solutions by all the solvers, but
the allocation of work need not have synchronization.)
Suppose two processes, p_0 and p_1, cooperate with one another so that they
generally operate independently and concurrently, but they occasionally share
information by p_0 sending information to p_1; with a synchronous send, p_0 can
procede after its send operation with the assurance that p_1 has received the
information. This communication paradigm is used in remote procedure call
(described in detail in Chapter 17).
9. If a set of processes are working on a common problem, i.e., the work has been
partitioned and delegated to various processes, then the run time will be reduced if all
the processes can execute at the same time. This follows because a fixed amount of
work is divided, then two or more processes perform parts of the work simultaneously
(in a system with multiple processors). Blocking receive operations tend to make a
process wait for one or more other processes to "catch up," reducing the effective
amount of concurrency in the execution. However, as we have seen in various
examples in Chapters 8 and 9, concurrent operation on shared information means that
it is necessary to incorporate a synchronization mechanism to manage sharing -- a
factor that considerably raises the complexity of the software.
10. Condition variables are used to suspend a process while it is logically in a critical
section. In a user thread package, the programmer controls the scheduling of threads
within an address space (process). Therefore, the programmer can determine
situations in which a thread is in a critical section, yet needs another critical section,
and thus can suspend the thread from executing until the needed critical section can

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
become available. Notice that this is not generally possible at the process level, since
there is not parent to control the schedule and to suspend other processes.
11. The Mach C thread cthread_fork() is similar to UNIX fork() in that it creates a
new thread. It is different in that the thread is given a specific procedure where it will
begin execution (same address space, but a different location from the parent thread).
When the C thread terminates, there is no synchronization with the parent thread.
12. This solution (with minor edits) provided by Don Lindsay, Fall, 1995.
===========================================================================
===========================================================================
/* parent.c
*
* Example program by Don Lindsay
*
*
* This program uses the trapezoidal rule to integrate
* f(x) = 1/(x+1)
* on [0,2]. It does this by forking N processes, each of which
* does n/N trapezoids.
* The parent specifies tasks over N pipes, and recieves answers over one
* shared pipe.
* The parent reports the totalled area, and reports the elapsed integration
* time, ie excluding the setup time. The time is the average of many runs.
* This program must be run with N between 1 and 8, and n=64.
*
* Tested on Linux: portability unknown.
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>>
#include <errno.h>
#include <fcntl.h>
#include <math.h>

#define REPEAT (4000)
#define NUMSTEPS (64)
#define PATHNAME "./child"

#define PRINT if(debug)fprintf
#define PRINT2 if(debug>1)fprintf
extern char **environ;

#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
typedef int Boolean;
/*typedef unsigned char u_char;*/

#define PIPE_IN (0)
#define PIPE_OUT (1)

int debug = 0;

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
int forkcount;
int pipes_to_child[8][2];
int pipe_from_child[2];

/****************************************************************
*
*/
void fatal( char *string )
{
fprintf( stderr, "FATAL ERROR: %s \\n", string );
exit(1);
}
/****************************************************************
*
*/
void system_fatal( char *string )
{
fprintf( stderr, "FATAL SYSTEM ERROR: ");
perror( string );
exit(1);
}
/****************************************************************
*
*/
void prompt()
{
fprintf( stderr, "TRY: parent N [ -d]\\n" );
exit(1);
}
/****************************************************************
*
* Sets globals forkcount, debug
*/
void parse_my_args( int argc, char **argv )
{
if( argc < 2 || argc > 3 ) prompt();
if( argc == 3 ){
if( strcmp( argv[2], " -d" ) == 0 )
debug = 1;
else if( strcmp( argv[2], " -D" ) == 0 )
debug = 2;
else
prompt();
}
forkcount = atoi( argv[1] );
PRINT( stderr, "forkcount %d \\n", forkcount );
if( forkcount < 1 || forkcount > 8 ) fatal( "arg out of range" );
}
/****************************************************************
*
* Fork that many children.
* Leaves global pipes_to_child and pipe_from_child. These are the
* stdin and stdout of each child.
* Exits on error.
*/
void fork_solvers( int forkcount )
{
int i;
pid_t pid;
char *child_argv[2];
child_argv[0] = PATHNAME;
child_argv[1] = NULL;

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
if( pipe( pipe_from_child )) system_fatal( "Pipe" );
for( i = 0; i < forkcount; i++ ) {
if( pipe( pipes_to_child[i] )) system_fatal( "Pipe" );

PRINT( stderr, "about to fork \\n" );
pid = fork();
if( pid == 0 ) {
/* I am the i'th child. */

if( close(0))
system_fatal("Close1");
if( dup( pipes_to_child[i][PIPE_IN ])== -1)system_fatal("dup1");
if( close(1))
system_fatal("Close2");
if( dup(pipe_from_child[ PIPE_OUT ])== -1)system_fatal("dup2");

/* child's stdin and stdout are now the pipes */

execve( PATHNAME, child_argv, environ );
fprintf( stderr, "exec of \\"%s\\" failed:\\n", PATHNAME );
system_fatal( "Child" );
exit(1);
}
/* I am the parent */
if( pid == -1 ) {
system_fatal( "Fork Parent" );
}
}
}
/***************************************************************
*
* Expects globals pipes_to_child, pipe_from_child.
* Writes step requests to those pipes, and returns the sum of the results.
*/
float farm_out_work( int forkcount )
{
u_char out_buf;
float in_buf;
int in_buf_len = sizeof( float );
float area;
int i, child;

/* Try to get them all working by writing all before any reads */

for( child = 0, i = 1; i <= NUMSTEPS; child++, i++ ) {
if( child >= forkcount ) child = 0; /* wrap around */

out_buf = i;
if( write( pipes_to_child[child][PIPE_OUT], &out_buf,1)!=1)
system_fatal( "write" );
}
for( area = 0.0, i = 1; i <= NUMSTEPS; i++ ) {
if( read( pipe_from_child[PIPE_IN], &in_buf,in_buf_len)
!= in_buf_len )
system_fatal( "read pipe" );
PRINT( stderr, "parent: %d gets area = %g \\n", i, in_buf );
area += in_buf;
}
PRINT( stderr, "parent: %d gets area = %g \\n", i, in_buf );
return area;
}
/****************************************************************
*

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
*
*/
void kill_solvers( int forkcount )
{
int i;
char out_buf;
out_buf = 0;

for( i = 0; i < forkcount; i++ ) {
if( write( pipes_to_child[i][PIPE_OUT], &out_buf,1)!=1)
system_fatal( "kill write" );
}
}
/******************************************************************
*
* Returns system time in milliseconds.
*/
double get_sys_time()
{
struct timeval t; /* int fields tv_sec, tv_usec */
double time;
int result = gettimeofday( &t, 0 );
if( result ) {
fprintf( stderr, "error from gettimeofday \\n" );
perror( "" );
exit(1);
}
PRINT( stderr, "%d %d \\n", t.tv_sec, t.tv_usec );
time = t.tv_sec * 1.e6 + t.tv_usec; /* in microseconds */
return time / 1000;
}
/****************************************************************
*/
main( int argc, char **argv )
{
double start, stop;
int i;
float area;

parse_my_args( argc, argv ); /* get forkcount */
fork_solvers( forkcount );

start = get_sys_time();
/* Must integrate many times to get a measurable amount of time. */
for( i = 0; i < REPEAT; i++ ) {
area = farm_out_work( forkcount );
}
stop = get_sys_time();

fprintf( stdout, "area is %g \\n", area );
fprintf( stdout, "time per integration is %g ms. \\n",
(stop-start)/REPEAT );
kill_solvers( forkcount );
exit(0);
}
===========================================================================
===========================================================================
/* child.c - to be invoked by "parent", forked integrator.
*
* Example program by Don Lindsay
*
*
* This program is used to integrate (via trapezoids) the function

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
*/
#define FUNC(x) (1/(x+1.0))
#define NUMSTEPS (64)
#define INTERVAL_LO (0.0)
#define INTERVAL_HI (2.0)

/* Reads 1-byte integers, one at a time, from stdin.
* A value in the range 1..NUMSTEPS causes a single trapezoid
* to be computed, and its area written (as a binary float) to stdout.
* Zero means quit: all else is a fatal error.
* Each trapezoid represents a 1/NUMSTEPS part of the INTERVAL.
*
* Tested on Linux: portability unknown.
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>


#define PRINT if(debug)fprintf
#define PRINT2 if(debug > 1)fprintf
extern char **environ;

typedef int Boolean;
/*typedef unsigned char u_char;*/

int debug = 0;
int forkcount;
/****************************************************************
*
*/
void fatal( char *string )
{
fprintf( stderr, "FATAL ERROR: %s \\n", string );
exit(1);
}
/****************************************************************
*
*/
void parse_args( int argc, char **argv )
{
if( argc != 1 ) {
fprintf( stderr, "Illegal arglist to child: %d \\n", argc );
exit(1);
}
}
/****************************************************************
*
*/
void system_fatal( char *string )
{
fprintf( stderr, "CHILD FATAL SYSTEM ERROR: ");
perror( string );
exit(1);
}

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
/****************************************************************
*
* Returns the area under f(x1)..f(x2) assuming f is linear between.
* Assumes x2 > x1.
* Expects macro FUNC.
*/
float trapezoid( float x1, float x2 )
{
float f1 = FUNC(x1);
float f2 = FUNC(x2);
return (x2-x1) * (f1+f2)/2.;
}
/****************************************************************
*
* Returns area of indexed trapezoid.
*/
float integrate( int index )
{
float x1, x2, deltax;

deltax = (INTERVAL_HI - INTERVAL_LO)/ NUMSTEPS;
x1 = INTERVAL_LO + index * deltax;
x2 = x1 + deltax;
return trapezoid( x1, x2 );
}
/****************************************************************
*/
main( int argc, char **argv )
{
int area_len = sizeof(float);
float area;
u_char buf;

parse_args( argc, argv );
for(;;) {
if( read( 0, &buf, 1 ) != 1 ) system_fatal( "read" );
PRINT( stderr, "child reads %d from pipe. \\n", buf );
if( buf == 0 ) exit(0);
if( buf > NUMSTEPS ) {
fprintf( stderr, "child: illegal %d read. \\n", buf );
exit(1);
}
area = integrate( buf -1 );
PRINT( stderr, "Child: area %d is %g \\n", buf, area );
if( write( 1, &area, area_len ) != area_len ) system_fatal( "write" );
}
}
13. Here is the quadrature problem using Mach C threads (with politically incorrect name
for the trapezoid solver code).
===========================================================================
===========================================================================
/* Trapezoidal Rule Quadrature using Mach C threads
*
* Use the following command to compile this file
* (assumed to be named trapezoid.c)
*
* trapezoid: trapezoid.o timer.o
* cc -g -o trapezoid trapezoid.o timer.o
*
* trapezoid.o: trapezoid.c

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
* cc -c trapezoid.c
*
*/


#include


/* #define TRUE 1 */
#define bottomRange 0.0
#define topRange 2.0
#define intervals 64
#define maxN 8

#define iLeft(i) 2*i+N
#define iRight(i) 2*i+N+1

/* Local function prototypes */
void solver(int);

/* Shared memory map
*
* Result from Solver 0
* Result from Solver 1
* ...
* Result from Solver N -1
* Left endpoint for Solver 0
* Right endpoint for Solver 0
* Left endpoint for Solver 1
* Right endpoint for Solver 1
* ...
* Left endpoint for Solver N -1
* Right endpoint for Solver N -1
*
* The memory descriptors follow ...
*/
float *shMem; /* Pointer to shared memory as floats */
char *cshMem; /* Pointer to shared memory as chars */

/* Locks for synchronization between solvers and master */
mutex_t resultLock[maxN];
mutex_t segLock[maxN];


extern int errno;
int N;


main (argc, argv)
int argc;
char *argv[];
{
cthread_t t_handle[maxN];
cthread_t cthread_fork();

float getTime();
float currentLeft, currentRight;
float length, result;
float startTime, stopTime;

int i, nAlive, solverNum;

unsigned lengthSM;

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»


/* Get a value of N from the command line */
if(argc == 2)
{
N = atoi(argv[1]);
if (N > maxN)
{
printf("Usage: N is too large \n");
exit(0);
};
}
else
{
printf("Usage: trapezoid N \n");
exit(0);
};

/* Initialize variables for the test */
result = 0.0;
length = (topRange-bottomRange)/(float)intervals;
currentLeft = bottomRange;
currentRight = bottomRange;
cthread_init(); /* Initialize the C threads package */

/* Create the shared memory */
lengthSM = 3*N*sizeof(float); /* See shared mem map above */
cshMem = malloc(lengthSM); /* Make the space be shared */
shMem = (float *) cshMem; /* Access the array as floats */


/* Create the N solvers */
for (i=0; i < N; i++)
{
shMem[iLeft(i)] = 0.0;
shMem[iRight(i)] = 0.0;
/* Setup locks on the buckets */
resultLock[i] = mutex_alloc();
mutex_lock(resultLock[i]);
segLock[i] = mutex_alloc();

/* Create the solver thread */
t_handle[i] = cthread_fork(solver, i);
};

nAlive = N;


/* This loop controls the dispatching of requests and processing of results
*/
startTime = getTime(); /* Starting time */
solverNum = 0;
while (nAlive > 0)
{
/* Wait for a message from a solver */
while (!mutex_try_lock(resultLock[solverNum]))
{
cthread_yield();
solverNum = (solverNum +1) % N;
};

/* Acquired lock */
result = result + shMem[solverNum];

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
/* Dispatch new work to the solver that just finished */
if (currentRight+length <= topRange)
{ /* Assign the next segment to the solver */
shMem[iLeft(solverNum)] = currentLeft;
shMem[iRight(solverNum)] = currentRight;
mutex_unlock(segLock[solverNum]);
currentLeft = currentRight;
currentRight = currentRight + length;
}
else
{ /* Eliminate the solver */
shMem[iLeft(solverNum)] = 1.0;
shMem[iRight(solverNum)] = 0.0;
mutex_unlock(segLock[solverNum]);
cthread_join(t_handle[solverNum]);
nAlive--;
};
};

/* All done -- Report the time & result for this iteration */
stopTime = getTime();
printf("%d processes required %6.2f seconds, result = %f \n",
N, stopTime-startTime, result);

exit(0);
}





/*------------ The Solver Thread Schema --------------- */

void solver(me)
int me;
{
float left, right;
float result;
int i;


/* Ask for initial work by writing a result of zero */
mutex_lock(segLock[me]); /* This should pass immediately */
shMem[me] = 0.0;
mutex_unlock(resultLock[me]);

left = 0.0;
right = 0.0;
while (TRUE)
{
/* Wait for a pair of endpoints */
mutex_lock(segLock[me]);
left = shMem[iLeft(me)];
right = shMem[iRight(me)];

/* Terminate if the left endpoint is greater than the right */
if (left > right) cthread_exit(0);

/* make the call measurable */
for (i=0;i < 1000;i++) cthread_yield();

shMem[me] = ((1.0/(left+1.0))+(1.0/(right+1.0)))/2.0*(right -
left);

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
mutex_unlock(resultLock[me]);
};

}
Here is the SOR problem using Mach C threads.
#include <stdio.h>
#include <cthreads.h>

#define MAX_N 4

/* Local function prototype */
void solver(int);

/* Shared memory among the threads */
mutex_t lock[MAX_N];
float A[MAX_N][MAX_N], b[MAX_N], x[MAX_N];

int N;

main(argc, argv)
int argc;
char *argv[];
{
FILE *data_fp, *fopen();
int i;
int tmp;
double double_eps;
float error, check();
float epsilon;
float solveX();
char data_filename[128];
char host_filename[128];

cthread_t t_handle[MAX_N];
cthread_t cthread_fork();

/* Get data from file; first, get the command line parameters ... */
if(argc == 3)
{
double_eps = atof(argv[1]);
epsilon = double_eps;
strcpy(data_filename, argv[2]);
}
else
{
printf("Usage: chaosMaster \n");
exit(0);
};

/* ... then read the data file */
printf("Opening %s ... \n", data_filename);
if((data_fp = fopen(data_filename, "r")) == NULL)
{
printf("Open on %s failed, exiting ... \n", data_filename);
exit(1);
};
fscanf(data_fp, "%d", &tmp);
N = tmp;
if(N > MAX_N)
{

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
printf("Degree %d is too large, halting ... \n", N);
exit(1);
};
for (i=0;i < N;i++)
fscanf(data_fp,"%f%f%f", &A[i][0], &A[i][1], &A[i][2]);
fscanf(data_fp,"%f %f %f", &b[0], &b[1], &b[2]);
fscanf(data_fp,"%f %f %f", &x[0], &x[1], &x[2]);
fclose(data_fp);

/* Echo the input */
printf("N = %d\n", N);
for (i=0;i < N;i++)
printf("A[%d][*] = %f %f %f \n", i, A[i][0], A[i][1],
A[i][2]);
printf("b[*] = %f %f %f \n", b[0], b[1], b[2]);
printf("x[*] = %f %f %f \n", x[0], x[1], x[2]);


/* Create the N solvers */
/* This is the code for dynamically defined (cthreads) N */
for (i=0; i < N; i++)
{
/* Initialize lock */
lock[i] = mutex_alloc();
t_handle[i] = cthread_fork(solver, i);
};

/* Solve the system */
error = 1000000.0;
while(error > double_eps)
{
/* Proceed only if all solvers are locked */
for (i=0; i < N; i++)
{
while(mutex_try_lock(lock[i]))
{ /* wasn't locked -- restore it*/
mutex_unlock(lock[i]);
cthread_yield();
};
};
error = check(A, x, b, N);
for (i=0; i < N; i++)
mutex_unlock(lock[i]);
cthread_yield();
};

printf("Solution x[*] = %f %f %f \n", x[0], x[1], x[2]);
printf(" With error factor = %f \n", error);
exit(0);
}


float check(A, x, b, n)
float A[][4], x[], b[];
int n;
{
int i, j;
float sum;
float error;

error = 0.0;
for(i=0; i < n; i++)
{

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
sum = 0.0;
for (j=0; j < n; j++)
sum = sum + A[i][j]*x[j];
error = error + (sum - b[i]);
};
if(error<0.0) error = -error;
return(error);
}


/*--------- The Solver Thread Schema -----------*/
void solver(me)
int me;
{
int j;

cthread_yield();
for(;;)
{
mutex_lock(lock[me]);
x[me] = b[me];
for (j=0;j < N; j++)
if(me!=j) x[me] = x[me] - A[me][j]*x[j];
x[me] = x[me]/A[me][me];
};
}

14. SOR with pipes
#include <stdio.h>
#include <signal.h>

#define MAX_N 4

int N;
double A[MAX_N][MAX_N], b[MAX_N];
int xout[MAX_N][2];
int xin[MAX_N][2];

int main(int argc, char *argv[]) {
double check(double [][MAX_N], double [], double [], int);
void solver(int);

FILE *data_fp, *fopen();
int i, j;
int status;
int solverPID[MAX_N];
double epsilon, newX;
double x[MAX_N];
char data_filename[128];



/*******************************************************/
/* Get the command line parameters ... */
if(argc == 3) {
sscanf(argv[1], "%lf", &epsilon);
strcpy(data_filename, argv[2]);
} else {
printf("Usage: sor \n");
exit(1);

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
};

/* Now read the data from the file */
printf("Epsilon = %lf, opening %s ... \n", epsilon, data_filename);
if((data_fp = fopen(data_filename, "r")) == NULL) {
printf("Open on %s failed, exiting ... \n", data_filename);
exit(1);
};
fscanf(data_fp, "%d", &N);
if(N > MAX_N) {
printf("Degree %d is too large, halting ... \n", N);
exit(1);
};
printf("N = %d\n", N);

/* Read the A matrix */
for (i=0; i < N; i++) {
for (j=0; j < N; j++) {
fscanf(data_fp,"%lf", &A[i][j]);
printf(" A[%d, %d] %lf", i, j, A[i][j]);
};
printf("\n");
};

/* Read the b vector */
for (j=0; j < N; j++) {
fscanf(data_fp,"%lf", &b[j]);
printf(" b[%d] %lf", j, b[j]);
};

/* Read the x vector guess */
printf("\n");
for (j=0; j < N; j++) {
fscanf(data_fp,"%lf", &x[j]);
printf(" x[%d] %lf", j, x[j]);
};

printf("\n");
fclose(data_fp);



/*******************************************************/
/* Create the N solvers */
for (i=0; i < N; i++) {
pipe(xin[i]); /* Pipe for solver[i] to return x[i]
*/
pipe(xout[i]); /* Pipe for solver[i] to get x[j] */
if((solverPID[i] = fork()) == 0) {;
solver(i); /* The i-th child runs this code */
exit(1); /* Never get here -- never returns */
};
};
/* The parent continues ... */

/*******************************************************/
/* Iteratively solve the system */
while(check(A, x, b, N) > epsilon) {
/* Distribute the newest x values*/
for (i=0; i < N; i++) {
for(j=0; j < N; j++)
if(j != i)

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
write(xout[i][1],
&x[j],sizeof(double));
};
/* Read x[i] from xin[i]. Since we cannot procede beyond
* this loop until ALL solvers have returned a value, we can
* use a blocking read here, i.e., we can wait for all in any order.
*/
for (i=0; i < N; i++)
read(xin[i][0], &x[i], sizeof(double));
};

/* Solution converged -- terminate the solvers */
for (i=0; i < N; i++) {
kill(solverPID[i], SIGTERM);
wait(&status);
};

/* Report the results */
printf("\nSolution with error factor = %lf: \n", check(A, x, b, N));
for (i=0; i < N; i++) {
printf(" x[%d] = %lf \n", i, x[i]);
};
printf("\n");
}


double check(double A[][MAX_N], double x[], double b[], int n) {
int i, j;
double sum, error;

error = 0.0;
for(i=0; i < n; i++) {
sum = 0.0;
for (j=0; j < n; j++)
sum = sum + A[i][j]*x[j];
error = error + (sum - b[i]);
};
if(error < 0.0) error = -error;
return(error);
}


/*--------- The Solver Schema -----------*/
void solver(int me) {
int i;
double x[MAX_N];

for(;;) {
/* Get new x values */
for(i=0; i < N; i++)
if(i != me)
read(xout[me][0], &x[i], sizeof(double));
x[me] = b[me];
for (i=0; i < N; i++)
if(i != me) x[me] = x[me] - A[me][i]*x[i];
x[me] = x[me]/A[me][me];
/* Return the new x[me] value */
write(xin[me][1], &x[me], sizeof(double));
};
}
15. This solution is provided by Sam Siewert, Spring, 1996.

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
Makefile:

#CFLAGS = -g -DDEBUG
CFLAGS = -g
CC = cc
SRC =
OBJ = ${SRC:.c=.o}
HDR =
MAINSRC = vt.c

.SUFFIXES: .c.o

vt: ${OBJ} ${MAINSRC} ${HDR}
${CC} ${CFLAGS} vt.c ${OBJ} -o $@

.c.o:
${CC} -c ${CFLAGS} $<

${OBJ}: ${HDR}

clean:
rm vt


Virtual Terminal Manager:

#include <signal.h>
#include <stdio.h>
#include <termio.h>
#include <unistd.h>
#include <fcntl.h>

#define TRUE 1
#define FALSE 0
#define NUMCOL 80
#define NUMLINES 25
#define NUM_VTS 2

struct vt_status_st {
int line;
int bufchars;
int total_lines_out;
int pid;
int running;
int inputchars;
int awaiting_newinput;
};

static struct vt_status_st vt_status[2];
static int active_vt = 0;
static int pipe_to_child_1[2];
static int pipe_to_child_2[2];
static int pipe_from_child_1[2];
static int pipe_from_child_2[2];

void vt_exit_handler()
{
int status;
int pid;

pid = wait(&status);

if(vt_status[0].pid == pid) {

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
fprintf(stderr, "vt0 exited \n");
close(pipe_from_child_1[0]);
close(pipe_to_child_1[1]);
vt_status[0].running = 0;
if(vt_status[1].running)
active_vt = 1;
else
exit(0);
}
else if(vt_status[1].pid == pid) {
fprintf(stderr, "vt1 exited \n");
close(pipe_from_child_2[0]);
close(pipe_to_child_2[1]);
vt_status[1].running = 0;
if(vt_status[0].running)
active_vt = 0;
else
exit(0);
}
else
fprintf(stderr, "somone else exited? \n");

}


void vt_abort()
{
write(STDERR_FILENO, "killing vts \n", 12);
fflush(stderr);

if(close(pipe_from_child_1[0]) == -1)
perror("close cp1 input");
if(close(pipe_to_child_1[1]) == -1)
perror("close pp1 output");
if(close(pipe_from_child_2[0]) == -1)
perror("close cp2 input");
if(close(pipe_to_child_2[1]) == -1)
perror("close pp2 output");

kill(vt_status[0].pid, SIGKILL);
kill(vt_status[1].pid, SIGKILL);

exit(-1);
}


main(int argc, char **argv)
{
int pid1, pid2, status, nbytes, i, j, val;
char buffer[NUMCOL];
char vt_buffer[NUM_VTS][NUMLINES][NUMCOL];
char vt_input_buffer[NUM_VTS][NUMCOL];
char c;
struct termio tiold, tinew;
int promptsynch, lastline;

/* clear screen to start */
system("clear");

/* terminal settings for character at a time input */
ioctl(STDIN_FILENO, TCGETA, &tiold);
tinew = tiold;
tinew.c_lflag &= ~ICANON;

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
tinew.c_lflag &= ~(ECHOCTL);
tinew.c_cc[VMIN] = 1;
tinew.c_cc[VTIME] = 0;

if(argc < 3 || argc > 4) {
fprintf(stderr, "usage: vt [ -promptsynch]\n");
exit(-1);
}
else if(argc == 4)
promptsynch = 1;
else /* argc must equal 3 */
promptsynch = 0;

/* trap child exit signals */
signal(SIGCHLD, vt_exit_handler);

/* deal with vt manager abort */
signal(SIGINT, vt_abort);

if(pipe(pipe_to_child_1) < 0) {
perror("parent pipe 1");
exit(-1);
}

if(pipe(pipe_to_child_2) < 0) {
perror("parent pipe 1");
exit(-1);
}

if(pipe(pipe_from_child_1) < 0) {
perror("child pipe 1");
exit(-1);
}

if(pipe(pipe_from_child_2) < 0) {
perror("child pipe 2");
exit(-1);
}

pid1 = fork();
vt_status[0].pid = pid1;

if (pid1 == 0) {
#ifdef DEBUG
printf("This is child 1 \n");
#endif

/* close write end of pipe_to_child_1 for child */
close(pipe_to_child_1[1]);

/* close read end of pipe_from_child_1 for child */
close(pipe_from_child_1[0]);

#ifdef DEBUG
write(pipe_from_child_1[1], "hello", 5);
nbytes = read(pipe_to_child_1[0], buffer, 5);
buffer[nbytes] = '\0';
printf("Child 1 hears parent %s \n", buffer);
#endif

/* so that write to pipe by VT manager sends data to execed stdin */
dup2(pipe_to_child_1[0], STDIN_FILENO);

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
/* so that read from pipe by VT manager gets data from execed stdout */
dup2(pipe_from_child_1[1], STDOUT_FILENO);

signal(SIGINT, SIG_IGN);
execlp(argv[1], argv[1], (char *)0);
}
else {
#ifdef DEBUG
printf("This is the parent \n");
#endif
pid2 = fork();
vt_status[1].pid = pid2;
if (pid2 == 0) {
#ifdef DEBUG
printf("This is child 2 \n");
#endif

/* close write end of pipe_to_child_2 for child */
close(pipe_to_child_2[1]);

/* close read end of pipe_from_child_2 for child */
close(pipe_from_child_2[0]);

#ifdef DEBUG
write(pipe_from_child_2[1], "hello", 5);
nbytes = read(pipe_to_child_2[0], buffer, 5);
buffer[nbytes] = '\0';
printf("Child 2 hears parent %s \n", buffer);
#endif

/* so that write to pipe by VT manager sends data to execed stdin */
dup2(pipe_to_child_2[0], STDIN_FILENO);

/* so that read from pipe by VT manager gets data from execed stdout
*/
dup2(pipe_from_child_2[1], STDOUT_FILENO);

signal(SIGINT, SIG_IGN);
execlp(argv[2], argv[2], (char *)0);
}
else {

/* close write end of child_pipes for parent */
close(pipe_from_child_1[1]);
close(pipe_from_child_2[1]);

/* close read end of parent_pipes for parent */
close(pipe_to_child_1[0]);
close(pipe_to_child_2[0]);

#ifdef DEBUG
printf("This is the parent \n");
nbytes = read(pipe_from_child_1[0], buffer, 5);
buffer[nbytes] = '\0';
printf("Parent hears child 1 %s \n", buffer);
nbytes = read(pipe_from_child_2[0], buffer, 5);
buffer[nbytes] = '\0';
printf("Parent hears child 2 %s \n", buffer);
write(pipe_to_child_1[1], "hello", 5);
write(pipe_to_child_2[1], "hello", 5);

#endif

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
vt_status[0].line = 0;
vt_status[1].line = 0;
vt_status[0].total_lines_out = 0;
vt_status[1].total_lines_out = 0;
vt_status[0].bufchars = 0;
vt_status[1].bufchars = 0;
vt_status[0].inputchars = 0;
vt_status[1].inputchars = 0;
vt_status[0].running = 1;
vt_status[1].running = 1;
vt_status[0].awaiting_newinput = 1;
vt_status[1].awaiting_newinput = 1;

ioctl(STDIN_FILENO, TCSETA, &tinew);

/* Make sure writes to child blocking */
val = fcntl(pipe_to_child_1[1], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_to_child_1[1], F_SETFL, val);

val = fcntl(pipe_to_child_2[1], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_to_child_2[1], F_SETFL, val);


/* Main Loop for VT Manager */

for(;;) {

/* read program output if any */
if(vt_status[0].awaiting_newinput) {
#ifdef DEBUG
printf("reading vt0 output \n");
#endif
vt_status[0].bufchars = 0;
/* initial blocking read for prompt synch. if applicable */
if(promptsynch) {
nbytes = read(pipe_from_child_1[0],

&(vt_buffer[0][vt_status[0].line][vt_status[0].bufchars]),
1);
}

/* set pipe non-blocking in case there is no output */
val = fcntl(pipe_from_child_1[0], F_GETFL, 0);
val |= O_NONBLOCK;
fcntl(pipe_from_child_1[0], F_SETFL, val);

do {
if(nbytes > 0) {
if(vt_buffer[0][vt_status[0].line][vt_status[0].bufchars] == ' \n')
{
#ifdef DEBUG
printf("vt0 read: %s", vt_buffer[0][vt_status[0].line]);
#endif
if(active_vt == 0) {
write(STDOUT_FILENO, vt_buffer[0][vt_status[0].line],
vt_status[0].bufchars+1);
}

vt_buffer[0][vt_status[0].line][vt_status[0].bufchars+1] = ' \0';
vt_status[0].line = (vt_status[0].line+1) % NUMLINES;
vt_status[0].total_lines_out++;

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
vt_status[0].bufchars = 0;
}
else
vt_status[0].bufchars++;
}
nbytes = read(pipe_from_child_1[0],

&(vt_buffer[0][vt_status[0].line][vt_status[0].bufchars]), 1);
} while(nbytes > 0);
#ifdef DEBUG
printf("vt0 read: %s", vt_buffer[0][vt_status[0].line]);
#endif
val = fcntl(pipe_from_child_1[0], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_from_child_1[0], F_SETFL, val);
if(active_vt == 0) {
write(STDOUT_FILENO, vt_buffer[0][vt_status[0].line],
vt_status[0].bufchars);
}
vt_status[0].awaiting_newinput = 0;
} /* end awaiting new input */

if(vt_status[1].awaiting_newinput) {
#ifdef DEBUG
printf("reading vt1 output \n");
#endif
vt_status[1].bufchars = 0;
/* initial blocking read for prompt synch. if applicable */
if(promptsynch) {
nbytes = read(pipe_from_child_2[0],

&(vt_buffer[1][vt_status[1].line][vt_status[1].bufchars]),
1);
}

/* set pipe non-blocking in case there is no output */
val = fcntl(pipe_from_child_2[0], F_GETFL, 0);
val |= O_NONBLOCK;
fcntl(pipe_from_child_2[0], F_SETFL, val);

do {
if(nbytes > 0) {
if(vt_buffer[1][vt_status[1].line][vt_status[1].bufchars] == ' \n')
{
#ifdef DEBUG
printf("vt1 read: %s", vt_buffer[1][vt_status[1].line]);
#endif
if(active_vt == 1) {
write(STDOUT_FILENO, vt_buffer[1][vt_status[1].line],
vt_status[1].bufchars+1);
}
vt_buffer[1][vt_status[1].line][vt_status[1].bufchars+1] = ' \0';
vt_status[1].line = (vt_status[1].line+1) % NUMLINES;
vt_status[1].total_lines_out++;
vt_status[1].bufchars = 0;
}
else
vt_status[1].bufchars++;
}
nbytes = read(pipe_from_child_2[0],

&(vt_buffer[1][vt_status[1].line][vt_status[1].bufchars]), 1);
} while(nbytes > 0);

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
#ifdef DEBUG
printf("vt1 read: %s", vt_buffer[1][vt_status[1].line]);
#endif
val = fcntl(pipe_from_child_2[0], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_from_child_2[0], F_SETFL, val);
if(active_vt == 1) {
write(STDOUT_FILENO, vt_buffer[1][vt_status[1].line],
vt_status[1].bufchars);
}
vt_status[1].awaiting_newinput = 0;
} /* end awaiting input */

/* get standard input to VT manager */
c = getchar();

if(c == '\e') {
c = getchar();
if(c == 'q')
vt_abort();
else if(c == 'c') {
if(vt_status[0].running && vt_status[1].running)
active_vt = (active_vt+1) % NUM_VTS;
#ifdef DEBUG
printf("active_vt = %ld \n", active_vt);
#endif
/* Write out active VT screen buffer to update display for
switch */
switch(active_vt) {
case 0:
#ifdef DEBUG
printf("writing out %ld vt lines \n",
vt_status[0].total_lines_out);
#endif
if(vt_status[0].total_lines_out > NUMLINES) {
j = (vt_status[0].line + 1) % NUMLINES;
lastline = NUMLINES - 1;
}
else {
j = 0;
lastline = vt_status[0].total_lines_out;
}
for(i=0;i<=lastline;i++) {
write(STDOUT_FILENO, vt_buffer[0][j],
strlen(vt_buffer[0][j]));
j = (j + 1) % NUMLINES;
}
write(STDOUT_FILENO, vt_input_buffer[0],
vt_status[0].inputchars);
break;
case 1:
#ifdef DEBUG
printf("writing out %ld vt lines \n",
vt_status[1].total_lines_out);
#endif
if(vt_status[1].total_lines_out > NUMLINES) {
j = (vt_status[1].line + 1) % NUMLINES;
lastline = NUMLINES - 1;
}
else {
j = 0;
lastline = vt_status[1].total_lines_out;
}

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
for(i=0;i<=lastline;i++) {
write(STDOUT_FILENO, vt_buffer[1][j],
strlen(vt_buffer[1][j]));
j = (j + 1) % NUMLINES;
}
write(STDOUT_FILENO, vt_input_buffer[1],
vt_status[1].inputchars);
break;
default:
write(STDERR_FILENO, "switch to unknown vt \n", 21);
}
}
} /* end if esc-c vt switch command */

/* VT manager standard input to be directed to active VT */
else {

switch(active_vt) {

case 0:
vt_input_buffer[0][vt_status[0].inputchars] = c;
vt_status[0].inputchars++;
if(c == '\n') {
vt_input_buffer[0][vt_status[0].inputchars] = ' \0';
strcat(vt_buffer[0][vt_status[0].line],
vt_input_buffer[0]);
#ifdef DEBUG
printf("vt0 written: %s", vt_input_buffer[0]);
#endif
write(pipe_to_child_1[1], vt_input_buffer[0],
vt_status[0].inputchars);
vt_status[0].inputchars = 0;
#ifdef DEBUG
printf("vt0 buffer line: %s",
vt_buffer[0][vt_status[0].line]);
#endif
vt_status[0].line = (vt_status[0].line+1) % NUMLINES;
vt_status[0].total_lines_out++;
vt_status[0].bufchars = 0;

do {
/* initial blocking read here assumes command results in
some
newline terminated output */
#ifdef DEBUG
printf("calling blocking read from child \n");
#endif
nbytes = read(pipe_from_child_1[0],

&(vt_buffer[0][vt_status[0].line][vt_status[0].bufchars]),
1);
#ifdef DEBUG
printf("nbytes = %ld \n", nbytes);
#endif
if(nbytes > 0) {
#ifdef DEBUG
printf("vt0 read char: %c",

vt_buffer[0][vt_status[0].line][vt_status[0].bufchars]);
#endif
if(vt_buffer[0][vt_status[0].line][vt_status[0].bufchars]
== '\n') {
#ifdef DEBUG

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
printf("vt0 read line: %s",
vt_buffer[0][vt_status[0].line]);
#endif
write(STDOUT_FILENO, vt_buffer[0][vt_status[0].line],
vt_status[0].bufchars+1);


vt_buffer[0][vt_status[0].line][vt_status[0].bufchars+1] = ' \0';
vt_status[0].line = (vt_status[0].line+1) % NUMLINES;
vt_status[0].total_lines_out++;
vt_status[0].bufchars = 0;

/* read any additional output non -blocking */
val = fcntl(pipe_from_child_1[0], F_GETFL, 0);
val |= O_NONBLOCK;
fcntl(pipe_from_child_1[0], F_SETFL, val);

}
else {
vt_status[0].bufchars++;
}
} /* end if bytes > 0 */
} while(nbytes > 0);

val = fcntl(pipe_from_child_1[0], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_from_child_1[0], F_SETFL, val);

if(vt_status[0].bufchars > 0) {
vt_buffer[0][vt_status[0].line][vt_status[0].bufchars] ==
'\0';
write(STDOUT_FILENO, vt_buffer[0][vt_status[0].line],
vt_status[0].bufchars);
vt_status[0].bufchars = 0;
}
else if(promptsynch) /* prompt not retrieved here */
vt_status[0].awaiting_newinput = 1;
}
break;

case 1:
vt_input_buffer[1][vt_status[1].inputchars] = c;
vt_status[1].inputchars++;
if(c == '\n') {
vt_input_buffer[1][vt_status[1].inputchars] = ' \0';
strcat(vt_buffer[1][vt_status[1].line],
vt_input_buffer[1]);
#ifdef DEBUG
printf("vt1 written: %s", vt_input_buffer[1]);
#endif
write(pipe_to_child_2[1], vt_input_buffer[1],
vt_status[1].inputchars);
vt_status[1].inputchars = 0;
#ifdef DEBUG
printf("vt1 buffer line: %s",
vt_buffer[1][vt_status[1].line]);
#endif
vt_status[1].line = (vt_status[1].line+1) % NUMLINES;
vt_status[1].total_lines_out++;
vt_status[1].bufchars = 0;

do {
/* initial blocking read here assumes command results

Gary Nutt, Operating Systems 3/e
Instructor’s Solutions
©2004 «GreetingLine»
in some output */
#ifdef DEBUG
printf("calling blocking read from child \n");
#endif
nbytes = read(pipe_from_child_2[0],

&(vt_buffer[1][vt_status[1].line][vt_status[1].bufchars]),
1);
#ifdef DEBUG
printf("nbytes = %ld \n", nbytes);
#endif
if(nbytes > 0) {
#ifdef DEBUG
printf("vt1 read char: %c",

vt_buffer[1][vt_status[1].line][vt_status[1].bufchars]);
#endif
if(vt_buffer[1][vt_status[1].line][vt_status[1].bufchars]
== '\n') {
#ifdef DEBUG
printf("vt1 read: %s",
vt_buffer[1][vt_status[1].line]);
#endif
write(STDOUT_FILENO, vt_buffer[1][vt_status[1].line],
vt_status[1].bufchars+1);


vt_buffer[1][vt_status[1].line][vt_status[1].bufchars+1] = ' \0';
vt_status[1].line = (vt_status[1].line+1) % NUMLINES;
vt_status[1].total_lines_out++;
vt_status[1].bufchars = 0;

val = fcntl(pipe_from_child_2[0], F_GETFL, 0);
val |= O_NONBLOCK;
fcntl(pipe_from_child_2[0], F_SETFL, val);

}
else {
vt_status[1].bufchars++;
}
}
} while(nbytes > 0);

val = fcntl(pipe_from_child_2[0], F_GETFL, 0);
val &= ~O_NONBLOCK;
fcntl(pipe_from_child_2[0], F_SETFL, val);

if(vt_status[1].bufchars > 0) {
vt_buffer[1][vt_status[1].line][vt_status[1].bufchars] ==
'\0';
write(STDOUT_FILENO, vt_buffer[1][vt_status[1].line],
vt_status[1].bufchars);
vt_status[1].bufchars = 0;
}
else if(promptsynch) /* prompt not retrieved here */
vt_status[1].awaiting_newinput = 1;
}
break;

default:
write(STDERR_FILENO, "input to unknown virtual terminal \n",
34);

Exploring the Variety of Random
Documents with Different Content

Then, too, the meetings and the partings, all
The playful quarrels in which lovers fall,
Serve to one end—each lover is a child,
Quick to resent and to be reconciled;
And then their peace brings kindness that remains,
And so the lover from the quarrel gains. 150
When he has fault that she reproves, his fear
And grief assure her she was too severe:
And that brings kindness—when he bears an ill,   }
Or disappointment, and is calm and still, }
She feels his own obedient to her will:}
And that brings kindness—and what kindness brings
I cannot tell you;—these were trying things.
They were as children, and they fell at length;
The trial, doubtless, is beyond their strength
Whom grace supports not; and will grace support 160
The too confiding, who their danger court?
Then they would marry—but were now too late—
All could their fault in sport or malice state;
And though the day was fix’d, and now drew on,
I could perceive my daughter’s peace was gone;
She could not bear the bold and laughing eye }
That gazed on her—reproach she could not fly; }
Her grief she would not show, her shame could not deny;  }
For some with many virtues come to shame,
And some that lose them all preserve their name. 170
“‘Fix’d was the day; but ere that day appear’d,
A frightful rumour through the place was heard;
War, who had slept awhile, awaked once more,
And gangs came pressing till they swept the shore:
Our youth was seized and quickly sent away,
Nor would the wretches for his marriage stay,
But bore him off, in barbarous triumph bore,
And left us all our miseries to deplore.
There were wives, maids, and mothers on the beach,
And some sad story appertain’d to each; 180

Most sad to Ruth—to neither could she go!
But sat apart, and suffer’d matchless wo!
On the vile ship they turn’d their earnest view, }
Not one last [look] allow’d,—not one adieu!}
They saw the men on deck, but none distinctly knew. }
And there she staid, regardless of each eye,
With but one hope, a fervent hope to die.
Nor cared she now for kindness—all beheld
Her, who invited none, and none repell’d;
For there are griefs, my child, that sufferers hide, 190
And there are griefs that men display with pride;
But there are other griefs that, so we feel,
We care not to display them nor conceal:
Such were our sorrows on that fatal day,
More than our lives the spoilers tore away;
Nor did we heed their insult—some distress }
No form or manner can make more or less,}
And this is of that kind—this misery of a press!  }
‘They say such things must be—perhaps they must;
But, sure, they need not fright us and disgust; 200
They need not soul-less crews of ruffians send
At once the ties of humble love to rend.
A single day had Thomas stay’d on shore,
He might have wedded, and we ask’d no more;
And that stern man, who forced the lad away,
Might have attended, and have graced the day;
His pride and honour might have been at rest,
It is no stain to make a couple blest!
Blest!—no, alas! it was to ease the heart
Of one sore pang, and then to weep and part! 210
But this he would not.—English seamen fight
For England’s gain and glory—it is right;
But will that public spirit be so strong,
Fill’d, as it must be, with their private wrong?
Forbid it, honour, one in all the fleet
Should hide in war, or from the foe retreat!

But is it just, that he who so defends
His country’s cause, should hide him from her friends?
Sure, if they must upon our children seize,
They might prevent such injuries as these; 220
Might hours—nay, days—in many a case allow,
And soften all the griefs we suffer now.
Some laws, some orders might in part redress
The licensed insults of a British press,
That keeps the honest and the brave in awe,
Where might is right, and violence is law.
‘Be not alarm’d, my child; there’s none regard
What you and I conceive so cruel-hard:
There is compassion, I believe; but still
One wants the power to help, and one the will, 230
And so from war to war the wrongs remain,
While Reason pleads, and Misery sighs, in vain.
‘Thus my poor Ruth was wretched and undone,
Nor had an husband for her only son,
Nor had he father; hope she did awhile,
And would not weep, although she could not smile;
Till news was brought us that the youth was slain,
And then, I think, she never smiled again;
Or if she did, it was but to express
A feeling far, indeed, from happiness! 240
Something that her bewilder’d mind conceived,
When she inform’d us that she never grieved,
But was right merry, then her head was wild,
And grief had gain’d possession of my child.
Yet, though bewilder’d for a time, and prone
To ramble much and speak aloud, alone;
Yet did she all that duty ever ask’d
And more, her will self-govern’d and untask’d.
With meekness bearing all reproach, all joy
To her was lost; she wept upon her boy, 250
Wish’d for his death, in fear that he might live
New sorrow to a burden’d heart to give.

‘There was a teacher, where my husband went— }
Sent, as he told the people—what he meant }
You cannot understand, but—he was sent.}
This man from meeting came, and strove to win
Her mind to peace by drawing off the sin,
Or what it was, that, working in her breast,
Robb’d it of comfort, confidence, and rest.
He came and reason’d, and she seem’d to feel 260
The pains he took—her griefs began to heal;
She ever answer’d kindly when he spoke,
And always thank’d him for the pains he took;
So, after three long years, and all the while
Wrapt up in grief, she blest us with a smile,
And spoke in comfort; but she mix’d no more
With younger persons, as she did before.
‘Still Ruth was pretty; in her person neat;
So thought the teacher, when they chanced to meet.
He was a weaver by his worldly trade, 270
But powerful work in the assemblies made;
People came leagues to town to hear him sift
The holy text,—he had the grace and gift;
Widows and maidens flock’d to hear his voice;
Of either kind he might have had his choice;—
But he had chosen—we had seen how shy
The girl was getting, my good man and I;
That when the weaver came, she kept with us,
Where he his points and doctrines might discuss;
But in our bit of garden, or the room 280
We call our parlour, there he must not come.
She loved him not, and though she could attend
To his discourses as her guide and friend,
Yet now to these she gave a listless ear,
As if a friend she would no longer hear;
This might he take for woman’s art, and cried,
‘Spouse of my heart, I must not be denied!’—
Fearless he spoke, and I had hope to see

My girl a wife—but this was not to be.
‘My husband, thinking of his worldly store, 290
And not, frail man, enduring to be poor,
Seeing his friend would for his child provide
And hers, he grieved to have the man denied;
For Ruth, when press‘d, rejected him, and grew
To her old sorrow, as if that were new.
‘Who shall support her?’ said her father, ‘how
Can I, infirm and weak as I am now?
And here a loving fool’——this gave her pain
Severe, indeed, but she would not complain;
Nor would consent, although the weaver grew 300
More fond, and would the frighten’d girl pursue.
‘O! much she begg’d him to forbear, to stand
Her soul’s kind friend, and not to ask her hand:
She could not love him.—‘Love me!’ he replied,
‘The love you mean is love unsanctified,
An earthly, wicked, sensual, sinful kind,
A creature-love, the passion of the blind.’
He did not court her, he would have her know,
For that poor love that will on beauty grow;
No! he would take her as the prophet took 310
One of the harlots in the holy book;
And then he look’d so ugly and severe!
And yet so fond—she could not hide her fear.
This fondness grew her torment; she would fly
In woman’s terror, if he came but nigh;
Nor could I wonder he should odious prove,
So like a ghost that left a grave for love.
But still her father lent his cruel aid
To the man’s hope, and she was more afraid:
He said, no more she should his table share, 320
But be the parish or the teacher’s care.
‘Three days I give you: see that all be right}
On Monday-morning—this is Thursday-night—   }
Fulfil my wishes, girl! or else forsake my sight!’  }

‘I see her now; and, she that was so meek
It was a chance that she had power to speak,
Now spoke in earnest—‘Father! I obey,
And will remember the appointed day!’
‘Then came the man: she talk’d with him apart,
And, I believe, laid open all her heart; 330
But all in vain—she said to me, in tears,
‘Mother! that man is not what he appears:
He talks of heaven, and let him, if he will,
But he has earthly purpose to fulfil;
Upon my knees I begg’d him to resign
The hand he asks—he said, ‘it shall be mine.
‘What! did the holy men of Scripture deign
To hear a woman when she said ‘refrain?’
Of whom they chose they took them wives, and these
Made it their study and their wish to please; 340
The women then were faithful and afraid,
As Sarah Abraham, they their lords obey’d,
And so she styled him; ’tis in later days
Of foolish love that we our women praise,
Fall on the knee, and raise the suppliant hand,
And court the favour that we might command.’
O! my dear mother, when this man has power,
How will he treat me—first may beasts devour!
Or death in every form that I could prove,
Except this selfish being’s hateful love.’ 350
I gently blamed her, for I knew how hard
It is to force affection and regard.
Ah! my dear lad, I talk to you as one
Who knew the misery of an heart undone;
You know it not; but, dearest boy, when man,
Do not an ill because you find you can.
Where is the triumph? when such things men seek,
They only drive to wickedness the weak.
Weak was poor Ruth, and this good man so hard,
That to her weakness he had no regard; 360

But we had two days peace; he came, and then
My daughter whisper’d, ‘Would there were no men!
None to admire or scorn us, none to vex
A simple, trusting, fond, believing sex;
Who truly love the worth that men profess,
And think too kindly for their happiness.’
Poor Ruth! few heroines in the tragic page
Felt more than thee in thy contracted stage;
Fair, fond, and virtuous, they our pity move,
Impell’d by duty, agonized by love; 370
But no Mandane, who in dread has knelt
On the bare boards, has greater terrors felt,
Nor been by warring passions more subdued
Than thou, by this man’s groveling wish pursued;
Doom’d to a parent’s judgment, all unjust,}
Doom’d the chance mercy of the world to trust, }
Or to wed grossness and conceal disgust. }
If Ruth was frail, she had a mind too nice
To wed with that which she beheld as vice;
To take a reptile, who, beneath a show 380
Of peevish zeal, let carnal wishes grow;
Proud and yet mean, forbidding and yet full
Of eager appetites, devout and dull;
Waiting a legal right that he might seize
His own, and his impatient spirit ease;
Who would at once his pride and love indulge,
His temper humour, and his spite divulge.
This the poor victim saw—a second time,
Sighing, she said, ‘Shall I commit the crime,
And now untempted? Can the form or rite 390
Make me a wife in my Creator’s sight?
Can I the words without a meaning say?
Can I pronounce love, honour, or obey?
And if I cannot, shall I dare to wed,
And go an harlot to a loathed bed?
Never, dear mother! my poor boy and I

Will at the mercy of a parish lie:
Reproved for wants that vices would remove,
Reproach’d for vice that I could never love,
Mix’d with a crew long wedded to disgrace, }400
A Vulgar, forward, equalizing race—}
And am I doom’d to beg a dwelling in that place?’  }
Such was her reasoning: many times she weigh’d
The evils all, and was of each afraid;
She loath’d the common board, the vulgar seat, }
Where shame, and want, and vice, and sorrow meet,  }
Where frailty finds allies, where guilt insures retreat. }
But peace again is fled; the teacher comes,
And new importance, haughtier air assumes.
No hapless victim of a tyrant’s love 410
More keenly felt, or more resisting strove
Against her fate; she look’d on every side,
But there were none to help her, none to guide;—
And he, the man who should have taught the soul,
Wish’d but the body in his base control.
She left her infant on the Sunday morn,
A creature doom’d to shame! in sorrow born;
A thing that languished, nor arrived at age
When the man’s thoughts with sin and pain engage—
She came not home to share our humble meal, 420
Her father thinking what his child would feel
From his hard sentence—still she came not home.
The night grew dark, and yet she was not come;
The east-wind roar’d, the sea return’d the sound,
And the rain fell as if the world were drown’d;
There were no lights without, and my good man,
To kindness frighten’d, with a groan began
To talk of Ruth, and pray; and then he took
The Bible down, and read the holy book;
For he had learning; and when that was done 430
We sat in silence—whither could we run?
We said, and then rush’d frighten’d from the door,

For we could bear our own conceit no more;
We call’d on neighbours—there she had not been;
We met some wanderers—ours they had not seen;
We hurried o’er the beach, both north and south,
Then join’d, and wander’d to our haven’s mouth,
Where rush’d the falling waters wildly out:
I scarcely heard the good man’s fearful shout,
Who saw a something on the billow ride, 440
And ‘Heaven have mercy on our sins!’ he cried,
‘It is my child!’ and to the present hour
So he believes—and spirits have the power.
And she was gone! the waters wide and deep
Roll’d o’er her body as she lay asleep.
She heard no more the angry waves and wind,
She heard no more the threatening of mankind;
Wrapt in dark weeds, the refuse of the storm,
To the hard rock was borne her comely form!
But O! what storm was in that mind? what strife, 450
That could compel her to lay down her life?
For she was seen within the sea to wade,
By one at distance, when she first had pray’d;
Then to a rock within the hither shoal
Softly and with a fearful step she stole;
Then, when she gain’d it, on the top she stood
A moment still—and dropt into the flood!
The man cried loudly, but he cried in vain—
She heard not then—she never heard again!
She had—pray, Heav’n!—she had that world in sight, 460
Where frailty mercy finds, and wrong has right;
But, sure, in this her portion such has been,
Well had it still remain’d a world unseen!’
Thus far the dame: the passions will dispense
To such a wild and rapid eloquence—
Will to the weakest mind their strength impart,
And give the tongue the language of the heart.”

TALES OF THE HALL.
BOOK VI.
ADVENTURES OF RICHARD, CONCLUDED.
Richard relates his Illness and Retirement
—A Village Priest and his two Daughters—
His peculiar Studies—His Simplicity of
Character—Arrival of a third Daughter—Her
Zeal in his Conversion— Their Friendship—
How terminated—An happy Day—Its
Commencement and Progress—A Journey
along the Coast—Arrival as a Guest—
Company—A Lover’s Jealousy—it increases—
dies away—- An Evening Walk—Suspense—-
Apprehension—Resolution—Certainty.
TALES OF THE HALL.
BOOK VI.
ADVENTURES OF RICHARD, CONCLUDED.

“This then, dear Richard, was the way you took
To gain instruction—thine a curious book,
Containing much of both the false and true;
But thou hast read it, and with profit too.
“Come, then, my Brother, now thy tale complete—
I know thy first embarking in the fleet,
Thy entrance in the army, and thy gain
Of plenteous laurels in the wars in Spain,
And what then follow’d; but I wish to know
When thou that heart hadst courage to bestow, 10
When to declare it gain’d, and when to stand
Before the priest, and give the plighted hand;
So shall I boldness from thy frankness gain
To paint the frenzy that possessed my brain;
For rather there than in my heart I found
Was my disease; a poison, not a wound,
A madness, Richard—but, I pray thee, tell
Whom hast thou loved so dearly and so well?”
The younger man his gentle host obey’d,
For some respect, though not required, was paid; 20
Perhaps with all that independent pride
Their different states would to the memory glide;
Yet was his manner unconstrain’d and free,
And nothing in it like servility.
Then he began:—“When first I reach’d the land,
I was so ill that death appear’d at hand;
And, though the fever left me, yet I grew
So weak ’twas judged that life would leave me too.
I sought a village-priest, my mother’s friend,
And I believed with him my days would end: 30
The man was kind, intelligent, and mild,
Careless and shrewd, yet simple as the child;
For of the wisdom of the world his share
And mine were equal—neither had to spare;
Else—with his daughters, beautiful and poor—
He would have kept a sailor from his door.

Two then were present, who adorn’d his home,
But ever speaking of a third to come;
Cheerful they were, not too reserved or free,
I loved them both, and never wish’d them three. 40
“The vicar’s self, still further to describe,
Was of a simple, but a studious tribe;
He from the world was distant, not retired,
Nor of it much possess’d, nor much desired:
Grave in his purpose, cheerful in his eye,
And with a look of frank benignity.
He lost his wife when they together past
Years of calm love, that triumph’d to the last.
He much of nature, not of man, had seen,
Yet his remarks were often shrewd and keen; 50
Taught not by books t’ approve or to condemn,
He gain’d but little that he knew from them;
He read with reverence and respect the few,
Whence he his rules and consolations drew;
But men and beasts, and all that lived or moved,
Were books to him; he studied them and loved.
“He knew the plants in mountain, wood, or mead;
He knew the worms that on the foliage feed;
Knew the small tribes that ’scape the careless eye,
The plant’s disease that breeds the embryo-fly; 60
And the small creatures who on bark or bough
Enjoy their changes, changed we know not how;
But now th’ imperfect being scarcely moves,
And now takes wing and seeks the sky it loves.
“He had no system, and forbore to read
The learned labours of th’ immortal Swede;
But smiled to hear the creatures he had known
So long, were now in class and order shown,
Genus and species—‘is it meet,’ said he,
‘This creature’s name should one so sounding be? 70
Tis but a fly, though first-born of the spring—
Bombylius majus, dost thou call the thing?

Majus, indeed! and yet, in fact, ’tis true,}
We all are majors, all are minors too, }
Except the first and last—th’ immensely distant two. }
And here again—what call the learned this?
Both Hippobosca and Hirundinis?
Methinks the creature should be proud to find
That he employs the talents of mankind;
And that his sovereign master shrewdly looks, 80
Counts all his parts, and puts them in his books.
Well! go thy way, for I do feel it shame
To stay a being with so proud a name.’
“Such were his daughters, such my quiet friend,
And pleasant was it thus my days to spend;
But when Matilda at her home I saw,
Whom I beheld with anxiousness and awe,
The ease and quiet that I found before
At once departed, and return’d no more.
No more their music soothed me as they play’d, 90
But soon her words a strong impression made:
The sweet enthusiast, so I deem’d her, took
My mind, and fix’d it to her speech and look;
My soul, dear girl! she made her constant care,  }
But never whisper’d to my heart ‘beware!’}
In love no dangers rise till we are in the snare.}
Her father sometimes question’d of my creed,
And seem’d to think it might amendment need;
But great the difference when the pious maid
To the same errors her attention paid: 100
Her sole design that I should think aright,
And my conversion her supreme delight.
Pure was her mind, and simple her intent,
Good all she sought, and kindness all she meant.
Next to religion friendship was our theme,
Related souls and their refined esteem.
We talk’d of scenes where this is real found,
And love subsists without a dart or wound;

But there intruded thoughts not all serene,
And wishes not so calm would intervene.” 110
“Saw not her father?”
“Yes; but saw no more
Than he had seen without a fear before:
He had subsisted by the church and plough,
And saw no cause for apprehension now.
We, too, could live; he thought not passion wrong,
But only wonder’d we delay’d so long.
More had he wonder’d had he known esteem
Was all we mention’d, friendship was our theme.—
Laugh, if you please, I must my tale pursue—}
This sacred friendship thus in secret grew }120
An intellectual love, most tender, chaste, and true;  }
Unstain’d, we said; nor knew we how it chanced
To gain some earthly soil as it advanced;
But yet my friend, and she alone, could prove
How much it differ’d from romantic love—
But this and more I pass—No doubt, at length,
We could perceive the weakness of our strength.
“O! days remember’d well! remember’d all!
The bitter-sweet, the honey and the gall;
Those garden rambles in the silent night, 130
Those trees so shady, and that moon so bright;
That thickset alley, by the arbour closed,
That woodbine seat where we at last reposed;
And then the hopes that came and then were gone,
Quick as the clouds beneath the moon passed on.
Now, in this instant, shall my love be shown,
I said—O! no, the happy time is flown!
“You smile; remember, I was weak and low,
And fear’d the passion as I felt it grow:
Will she, I said, to one so poor attend, 140
Without a prospect, and without a friend?
I dared not ask her—till a rival came,
But hid the secret, slow-consuming flame.

I once had seen him; then familiar, free,
More than became a common guest to be;
And sure, I said, he has a look of pride
And inward joy—a lover satisfied.
Can you not, Brother, on adventures past
A thought, as on a lively prospect, cast?
On days of dear remembrance! days that seem, 150
When past—nay, even when present—like a dream?
These white and blessed days, that softly shine
On few, nor oft on them—have they been thine?”
George answer’d, “Yes! dear Richard, through the years
Long past, a day so white and mark’d appears.
As in the storm that pours destruction round,
Is here and there a ship in safety found:
So in the storms of life some days appear
More blest and bright for the preceding fear.
These times of pleasure that in life arise, 160
Like spots in deserts, that delight, surprise,
And to our wearied senses give the more,
For all the waste behind us and before—
And thou, dear Richard, hast then had thy share
Of those enchanting times that baffle care?”
Yes, I have felt this life-refreshing gale
That bears us onward when our spirits fail;
That gives those spirits vigour and delight—
I would describe it, could I do it right.
Such days have been—a day of days was one 170
When, rising gaily with the rising sun,
I took my way to join a happy few,
Known not to me, but whom Matilda knew,
To whom she went a guest, and message sent:
Come thou to us;’ and as a guest I went.
There are two ways to Brandon—by the heath
Above the cliff, or on the sand beneath,
Where the small pebbles, wetted by the wave,
To the new day reflected lustre gave.

At first above the rocks I made my way, 180
Delighted looking at the spacious bay,
And the large fleet that to the northward steer’d
Full sail, that glorious in my view appear’d;
For where does man evince his full control
O’er subject matter, where displays the soul
Its mighty energies with more effect
Than when her powers that moving mass direct?
Than when man guides the ship man’s art has made,
And makes the winds and waters yield him aid?
“Much as I long’d to see the maid I loved, 190
Through scenes so glorious I at leisure moved;
For there are times when we do not obey
The master-passion—when we yet delay—
When absence, soon to end, we yet prolong,
And dally with our wish although so strong.
“High were my joys, but they were sober too,
Nor reason spoil’d the pictures fancy drew;
I felt—rare feeling in a world like this—
The sober certainty of waking bliss;
Add too the smaller aids to happy men, 200
Convenient helps—these too were present then.
“But what are spirits? light indeed and gay }
They are, like winter flowers, nor last a day; }
Comes a rude icy wind—they feel, and fade away.  }
“High beat my heart when to the house I came,
And when the ready servant gave my name;
But when I enter’d that pernicious room,
Gloomy it look’d, and painful was the gloom;
And jealous was the pain, and deep the sigh
Caused by this gloom, and pain, and jealousy: 210
For there Matilda sat, and her beside
That rival soldier, with a soldier’s pride;
With self-approval in his laughing face,
His seem’d the leading spirit of the place.
She was all coldness—yet I thought a look,

But that corrected, tender welcome spoke:
It was as lightning which you think you see,
But doubt, and ask if lightning it could be.
“Confused and quick my introduction pass’d,
When I, a stranger and on strangers cast, 220
Beheld the gallant man as he display’d
Uncheck’d attention to the guilty maid.
O! how it grieved me that she dared t’ excite
Those looks in him that show’d so much delight;
Egregious coxcomb! there—he smiled again,
As if he sought to aggravate my pain;
Still she attends—I must approach—and find,
Or make, a quarrel, to relieve my mind.
“In vain I try—politeness as a shield
The angry strokes of my contempt repell’d; 230
Nor must I violate the social law
That keeps the rash and insolent in awe.
Once I observed, on hearing my replies,
The woman’s terror fix’d on me the eyes
That look’d entreaty; but the guideless rage
Of jealous minds no softness can assuage.
But, lo! they rise, and all prepare to take
The promised pleasure on the neighbouring lake.
“Good heaven! they whisper! Is it come to this?
Already!—then may I my doubt dismiss: 240
Could he so soon a timid girl persuade?
What rapid progress has the coxcomb made!
And yet how cool her looks, and how demure!
The falling snow nor lily’s flower so pure—
What can I do? I must the pair attend,
And watch this horrid business to its end.
“There, forth they go! He leads her to the shore—
Nay, I must follow—I can bear no more:
What can the handsome gipsy have in view
In trifling thus, as she appears to do? 250
I, who for months have labour’d to succeed,

Have only lived her vanity to feed.
“O! you will make me room—’tis very kind,
And meant for him—it tells him he must mind;
Must not be careless:—I can serve to draw
The soldier on, and keep the man in awe.
O! I did think she had a guileless heart,
Without deceit, capriciousness, or art;
And yet a stranger, with a coat of red,
Has, by an hour’s attention, turn’d her head. 260
“Ah! how delicious was the morning-drive,
The soul awaken’d, and its hopes alive;
How dull this scene by trifling minds enjoy’d,
The heart in trouble and its hope destroy’d.
Well, now we land—And will he yet support
This part? What favour has he now to court?
Favour! O, no! He means to quit the fair;
How strange! how cruel! Will she not despair?
Well! take her hand—no further if you please,
I cannot suffer fooleries like these:— 270
How? ‘Love to Julia!’ to his wife?—O! dear }
And injured creature, how must I appear,  }
Thus haughty in my looks, and in my words severe? }
Her love to Julia, to the school-day friend
To whom those letters she has lately penn’d!
Can she forgive? And now I think again,
The man was neither insolent nor vain;
Good humour chiefly would a stranger trace,
Were he impartial, in the air or face;
And I so splenetic the whole way long, 280
And she so patient—it was very wrong.
The boat had landed in a shady scene;
The grove was in its glory, fresh and green;
The showers of late had swell’d the branch and bough,
And the sun’s fervour made them pleasant now.
Hard by, an oak arose in all its pride,
And threw its arms along the water’s side:

Its leafy limbs, that on the glassy lake
Stretch far, and all those dancing shadows make.
And now we walk—now smaller parties seek 290
Or sun or shade as pleases—Shall I speak?
Shall I forgiveness ask, and then apply
For——O! that vile and intercepting cry!
Alas! what mighty ills can trifles make—
An hat! the idiot’s—fallen in the lake!
What serious mischief can such idlers do?
I almost wish the head had fallen too.
No more they leave us, but will hover round,
As if amusement at our cost they found;
Vex’d and unhappy I indeed had been, 300
Had I not something in my charmer seen
Like discontent, that, though corrected, dwelt
On that dear face, and told me what she felt.
“Now must we cross the lake, and as we cross’d
Was my whole soul in sweet emotion lost;
Clouds in white volumes roll’d beneath the moon,
Softening her light that on the waters shone:
This was such bliss! even then it seem’d relief
To veil the gladness in a show of grief.
We sigh’d as we conversed, and said, how deep 310
This lake on which those broad dark shadows sleep;
There is between us and a watery grave
But a thin plank, and yet our fate we brave.
‘What if it burst?’ ‘Matilda, then my care }
Would be for thee: all danger I would dare,  }
And, should my efforts fail, thy fortune would I share.’  }
‘The love of life,’ she said, ‘would powerful prove!’—
‘O! not so powerful as the strength of love.’—
A look of kindness gave the grateful maid,
That had the real effort more than paid. 320
“But here we land, and haply now may choose
Companions home—our way, too, we may lose:
In these drear, dark, inosculating lanes,

The very native of his doubt complains;
No wonder then that in such lonely ways
A stranger, heedless of the country, strays;
A stranger, too, whose many thoughts all meet
In one design, and none regard his feet.
“‘Is this the path?’ the cautious fair one cries;}
I answer, ‘Yes!’—‘We shall our friends surprise,’  }330
She added, sighing—I return the sighs. }
“‘Will they not wonder?’ ‘O! they would, indeed,
Could they the secrets of this bosom read,
These chilling doubts, these trembling hopes I feel!
The faint, fond hopes I can no more conceal—
I love thee, dear Matilda!—to confess
The fact is dangerous, fatal to suppress.
“‘And now in terror I approach the home
Where I may wretched but not doubtful come;
Where I must be all ecstasy, or all— 340
O! what will you a wretch rejected call?
Not man, for I shall lose myself, and be
A creature lost to reason, losing thee.
“‘Speak, my Matilda! on the rack of fear
Suspend me not—I would my sentence hear,
Would learn my fate—Good Heaven! and what portend
These tears?—and fall they for thy wretched friend?
Or’——but I cease; I cannot paint the bliss,
From a confession soft and kind as this;
Nor where we walk’d, nor how our friends we met, }350
Or what their wonder—I am wondering yet;}
For he who nothing heeds has nothing to forget.}
“All thought, yet thinking nothing—all delight
In every thing, but nothing in my sight!
Nothing I mark or learn, but am possess’d  }
Of joys I cannot paint, and I am bless’d }
In all that I conceive—whatever is, is best. }
Ready to aid all beings, I would go
The world around to succour human wo;

Yet am so largely happy, that it seems 360
There are no woes, and sorrows are but dreams.
“There is a college joy, to scholars known,
When the first honours are proclaim’d their own;
There is ambition’s joy, when in their race
A man surpassing rivals gains his place;
There is a beauty’s joy, amid a crowd
To have that beauty her first fame allow’d;
And there’s the conqueror’s joy, when, dubious held
And long the fight, he sees the foe repell’d.
“But what are these, or what are other joys, 370
That charm kings, conquerors, beauteous nymphs and boys,
Or greater yet, if greater yet be found,
To that delight when love’s dear hope is crown’d?
To the first beating of a lover’s heart,
When the loved maid endeavours to impart,
Frankly yet faintly, fondly yet in fear,
The kind confession that he holds so dear?
Now in the morn of our return how strange
Was this new feeling, this delicious change;
That sweet delirium, when I gazed in fear, 380
That all would yet be lost and disappear.
“Such was the blessing that I sought for pain,
In some degree to be myself again;
And when we met a shepherd old and lame,
Cold and diseased, it seem’d my blood to tame;
And I was thankful for the moral sight,
That soberized the vast and wild delight.”

TALES OF THE HALL.
BOOK VII.
THE ELDER BROTHER.
Conversation—Story of the elder Brother
—His romantic Views and Habits—The Scene
of his Meditations—Their Nature—
Interrupted by an Adventure—The
Consequences of it—A strong and
permanent Passion—Search of its Object—
Long ineffectual—How found—The first
Interview—The second—End of the
Adventure—Retirement.
TALES OF THE HALL.
BOOK VII.
THE ELDER BROTHER.