CMPSC
311,
Introduction to Systems Programming
Course Intro
Reading
- Bryant & O'Hallaron, CS:APP, Preface; Ch. 1, A Tour of
Computer Systems
- Sec. 1.1-1.8; what happens when a program runs?
- Sec. 1.9-1.10; Important Themes, Summary
- King, CP:AMA, Preface; Ch. 1, Introducing C
- The CS:APP chapter introductions provide a nice overview and
perspective. Start with these:
- Ch. 2, Representing and Manipulating Information, p. 30-33
- Ch. 3, Machine-Level Representation of Programs, p. 154-156
- App. A, Error Handling, p. 999; Sec. 8.3, System Call Error
Handling
- CS:APP Ch. 3 is a nice adjunct to the topics covered in CMPEN
331, Computer Organization
and Design. Some parts of Ch. 3 will be required reading
for the
CMPSC 311 assignments.
Extra Reading
Let's start with three questions
- What is Systems Programming?
- What do System Programs provide?
- What are the issues facing System Programmers?
What is Systems Programming?
- tools for resource management
- tools for programmers
- tools for non-programmers, sometimes
- "System Programming" is an equivalent term. "Application
Programming" is not.
What do System Programs provide?
- Infrastructure and Abstraction
- generic tools, not restricted to any specific user-related
task
- layered interfaces to the system hardware
- support for application programs
- operating systems
- provide methods for connecting hardware and software
components
- The active software components are processes and threads,
executing
concurrently.
- The hardware components are processors, memory, external
devices, and links between them.
- manage resources
- allocate resources, prevent their misuse
- time, space, bandwidth, power, etc.
- Processes are allocated exclusive use of hardware
components
for a limited period of time, so time is a resource.
- provide abstractions of the resources
- processor –> instruction set architecture, assembly
language
- processor, main memory –> processes and threads,
address
space
- main memory, disk memory –> virtual memory
- disk memory, I/O devices –> files, networks
- whole system –> virtual machine
- map abstract resources to virtual resources over time
- map virtual resources to actual resources over time
- resource scheduling and virtualization, part of managing
the
resources
- device drivers
- implement a direct interface to the hardware
- the author of this part sees the actual device
- correct operation may require extra privileges from the OS
- this probably requires low-level specific knowledge of the
device
- implement a function-call interface to the direct device
interface
- the user of this part (the caller of the function) sees an
abstract device defined by the function
- visible – input, output including status information
- maybe not visible – internal state
- maybe important? – timing, fault conditions, etc.
- infrastructure – devices can be used from high-level
languages
- abstraction – hide the details from programmers who
usually
don't need them
- system utilities
- programs that require access to system resources, and are
application-independent
- generally provided with the operating system
- compilers, assemblers, linkers, loaders
- translate programs from high-level or low-level to
machine-level
- connect previously-translated program modules
- load an executable file into memory, start a new process
- editors
- programming languages
- methods of expressing algorithms
- including, common data structures and function libraries
- methods for connecting software components
- see Ousterhout's article for some more ideas
- etc., etc.
What are the issues facing System Programmers?
- System quality is important.
- Build high-quality products that perform useful functions in
a
predictable way at a reasonable cost.
- Programmer productivity is important.
- Improve the quality of products, and the design processes
that
lead to them.
- Resource usage is important.
- Understand how your programs use the available resources of
the
computer (time, space, bandwidth, power, etc.).
- User productivity is important.
- Understand how your tools and programs affect the users of
the
system,
and the tasks they perform.
- Hardware technology changes.
- Programs should be portable.
- Software standards encourage portability and long-term
survival.
- Systems are large, small, and everything in between.
- Sometimes you need to build your own complete support
structure.
- Everything is connected.
- Design programs as cooperating components.
- But, you can't always predict when the parts will try to
interact.
- Systems must run reliably forever.
- Use the system resources responsibly.
- Recover from errors and continue running.
- Systems are under attack.
- Design and write code that is demonstrably correct and
secure.
- Correctly handle all errors and special situations.
- Diagnose and report problems as they occur, or record them
for
later analysis.
Abstraction and Implementation
- Abstraction helps us deal with complexity – it hides
lower-level
detail.
- Abstraction helps to extend the system's capabilities –
software operations are built from sequences of simpler hardware
and software operations.
- Layers of abstraction
- system-level (hardware)
- system-level (software)
- application-level
- Instruction set architecture (ISA)
- those parts of the processor visible to the programmer
- individual machine instructions, their formats and semantics
- sequences of machine instructions for specific tasks
- protocols for design of common components
- the hardware/software interface
- Application binary interface (ABI)
- the ISA plus the system software interface
- Implementation
- the details underlying an interface
- You can change an implementation without changing the
interface, if the interface is well-designed.
Modern systems are built by connecting components.
- Interfaces between components can be standardized.
- for example, a function library
- function parameters and return value
- action of the function when given valid data
- action of the function when given invalid data
- ? internal state, retained between calls
- defined as part of ...
- a programming language
- an operating system
- an application program
- etc.
- Concurrency infrastructure
- more than one operation at a time
- multiple operands in one instruction
- multiple functional units in one instruction execution
unit
- more complicated single instructions
- multiple instructions from one instruction sequence
- single instructions from multiple instruction sequences
- multiple threads in one instruction core
- multiple instruction cores in one processor
- multiple processors and multiple devices in one subsystem
- multiple subsystems in one system
- asynchronous operations
- many events, at unpredictable times, in an unpredictable
order
- software abstractions of concurrency and asynchronous
operation
- signals, abstractions of hardware interrupts
- multiple threads in one process
- multiple processes in one system
- time-sharing, thread and process scheduling on a
resource-limited system
- Communication infrastructure
- local
- between functions in one thread
- between threads in one process
- between processes on one system
- non-local
- between processes on separate systems
- between systems on one network
- between systems on different networks
- communication protocol
- the rules of information exchange between two or more
components
- expected data formats and control signals
- timing and ordering of data delivery and control signals
Some examples of system components used by a large application
program
- network control
- security policy and enforcement
- user interface
- keyboard, mouse, microphone, camera, ...
- visual display, speakers
- data management
- etc.
This course is intended to provide background information and
programming experience to prepare you for more detailed and broader
studies of the internals of Operating Systems, and the principles
and
practice of Software Engineering.
In this course,
- We will concentrate on the C programming language and the Unix
operating system.
- We will pay attention to the software standards for C and
Unix.
- We will cover some topics in a lot of detail, and give a lot
of
examples to illustrate the concepts.
- You will be expected to write programs that are correct, and
are
obviously correct.
- You will be expected to try a lot of simple programs, to
increase
your understanding.
- You will learn more about how an operating system works, by
using
the tools that Unix provides.
- The only way to learn this subject well is to write and
rewrite a
lot of programs.
- Don't limit your programming to the homework assignments.
We will assume that you know
- C++ and Java
- object-oriented programming and development of classes
- how to write a program using an integrated development
environment
- how to go off and learn something on your own (with
suggestions)
We will not assume that you know anything about
- Unix, Linux or Mac OS X
- pointers
By the end of the course, if successful, you will know a lot about
- Unix, especially Solaris and Linux
- C, the language and libraries
- pointers and dynamically-allocated data structures
- asynchronous operations
- diagnosing faulty programs and faulty designs
- how to go off and learn something on your own (without
suggestions)
System programming is about tool building, so you need to understand
- generalities of tools
- specifics of particular tools
- selection of appropriate tools
- evaluation of tools for correctness and efficiency
Some of the programming tools we will discuss are command-line
shells
and text editors. You might suffer withdrawal symptoms from
going
without your fancy graphics display and mouse.
System programming requires you to
be
aware of the resources that your
program uses.
Exercise
- How many instructions are executed when this C program
runs? How long does it take to execute? How much
memory
does it use? What message is printed when the program
runs?
If you compile the program with optimization turned on, why does
it
take longer to
execute?
void foo(void) { int bar;
foo(); }
int main(void) { foo(); return 0; }
Exercise
- You like to watch a movie while you work.
- The program you are writing and testing has a lot of bugs and
runs slowly.
- Why?
Exercise
- You are connected to a remote system.
- How long does it take to transmit monocolor text, 25 lines by
80
columns, compared to 256-color graphics at 1024 by 768 pixels?
- Compare a dial-up modem at 57,600 bits per second, and a DSL
line
at 768,000 bits per second.
- What did you assume about the data representation of
characters
and pixels?
- How much data actually needs to be transmitted? (maybe
it's
faster than you thought)
- What features of data transmission did you ignore?
(maybe
it's slower than you thought)
Exercise
- Write a C program without using a keyboard.
Exercise, to test your tolerance for ambiguity
- For all the programming tools, and all the programs, that you
use
on a regular basis, classify them as "system program" or
"application
program".
- Explain why Java is not a system programming language.
- (This one is good for starting an argument.) Explain why
C++ is not a system programming language.
Exercise
- Your program is reading an input file, and the actual input
doesn't agree with the expected form or properties of "correct"
input. Should your program ...
- ignore the problem and keep going.
- check the input as you go, report an error if you find one,
and
keep going.
- check the input as you go, open a dialog box with the user if
you
find an error, and refuse to continue until you get valid data.
- check the input as you go, report an error if you find one,
and
then quit.
- work as 2, 3 or 4, but also send an email message to yourself
so
you know what kind of mistakes the users are making; this should
help
you improve the program and documentation.
Exercise
- The programming language C is defined by its syntax (the form of a program) and
semantics
(the meaning of a
program). The semantics are described in terms of an
abstract
machine and the environment in which it runs. The abstract
execution environment considers memory and files that a program
could
modify, among other things. Why not just choose an actual
machine
and an actual environment, and avoid the abstractions?
Exercises
- Write a C++ function using reference parameters, and its
equivalent in C.
- C doesn't have reference parameters, so you need to do
something else.
- Describe a method for transforming any C++ function that uses
reference parameters into an equivalent C function.
- Write two C++ functions with the same name, using function
overloading, and their equivalent functions in C.
- C doesn't have function overloading, so you need to do
something else.
- Describe a method for transforming any set of C++ functions into an
equivalent set of C functions.
- Write a C++ class definition, with some methods but without
operator overloading, and its equivalent in C.
- C doesn't have classes, so you need to do something else.
- Describe a method for transforming any reasonably simple C++ class
into an equivalent C data type and set of functions.
- Congratulations, you are now the first C++ compiler.
Some initial concepts and vocabulary
- system call
- a request to the OS for service
- system-specific (OS-specific and perhaps
device-specific)
- system function
- a wrapper around a system call
- not so system-specific (OS-specific but not
device-specific)
- library function
- a wrapper around one or more system functions
- largely system independent
Example
__open() is the Solaris version-specific system
call
to open a file
- Solaris is the version of Unix from Sun Microsystems
Oracle
Corp.
- like all operating systems, it is updated over time
copen() is the Solaris system function to open a
file
- this is a simplified view of the real situation
open() is the Posix standard library function to
open a file, unbuffered
- Posix is the standard for Unix and Unix-like operating
systems
fopen() is the C standard library function to
open a
file, buffered
fopen() is OS-independent
- We will discuss
open() and fopen()
but not anything at a lower level.
- You will use
open() and fopen() in
your programming projects.
If you want to see some real code, take a look at these from
OpenSolaris.
- define common assembly-language code sequences for system
calls,
Intel x86
version
- system call numbers,
#define SYS_open
_syscall(), for entry into the OS, Intel x86
version, assembly code
open_com() checks for special cases and calls _syscall(SYS_open,
path,
nflags,
mode)
open() calls bc_open() which checks
the parameters and calls open_com()
fopen() calls _endopen() which
calls open()
Infrastructure
- Try to think of "look under the hood", not "crawl
down the
sewer", though both are relevant at times.
- Low-level system software must be able to work in
resource-constrained environments, and run efficiently with
little
overhead.
- Low-level system software is often machine-dependent, for
example
written in an assembly language with specific assumptions about
the
hardware. C allows you to work at this level with rare
need for
assembly language programming, and also to work at a
higher-level for
machine-independent code. Well-designed system software
should be
(mostly) machine-independent.
- You must always be able to estimate what the compiler will do
when translating your program, and what the machine will do when
executing it.
- You need a good "mental model" of how computer systems work.
Exercise
- Does an iPhone represent a resource-constrained environment,
or a
resource-rich environment?
- Is an iPhone app an example of low-level system software,
high-level system software, or an application program?
- Which programming language is typically used to implement an
iPhone app?
- Which programming language is used to implement the low-level
system software on an iPhone?
Everyone's first example. (% is the command-line
prompt)
% cd /tmp
% vi hello.c
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
% cc -o hello
hello.c
% hello
hello, world
% ./hello
hello, world
What did the compiler actually do? It created an executable
file. On Solaris, ...
% ls -l hello*
-rwx------ 1 dheller
fcse 6988 Aug 21 15:39
hello
-rw------- 1 dheller
fcse 68
Aug 21
15:38 hello.c
% file hello*
hello: ELF
32-bit
MSB executable SPARC32PLUS Version 1, V8+ Required, dynamically
linked,
not stripped
hello.c: c program
text
(ELF = Executable and Linking Format)
What is in the executable file?
% od -x hello
0000000 7f45 4c46 0102 0100 0000 0000 0000 0000
0000020 0002 0012 0000 0001 0001 0670 0000 0034
0000040 0000 1764 0000 0100 0034 0020 0005 0028
0000060 0019 0018 0000 0006 0000 0034 0001 0034
... further output omitted
% od -c hello
0000000 177 E L F 001 002
001
\0 \0 \0 \0 \0 \0 \0
\0
\0
0000020 \0 002 \0 022 \0 \0 \0
001
\0 001 006 p \0 \0 \0
4
0000040 \0 \0 027 d \0 \0
001
\0 \0 4 \0
\0
005 \0 (
0000060 \0 031 \0 030 \0 \0 \0
006
\0 \0 \0 4 \0 001
\0 4
... further output omitted
The executable file contains machine instructions and organizational
information.
% elfdump hello
ELF Header
ei_magic: { 0x7f, E, L, F }
ei_class:
ELFCLASS32
ei_data: ELFDATA2MSB
e_machine:
EM_SPARC32PLUS
e_version: EV_CURRENT
e_type: ET_EXEC
e_flags: [ EF_SPARC_32PLUS ]
e_entry:
0x10670
e_ehsize:
52
e_shstrndx:
24
e_shoff:
0x1764
e_shentsize:
40
e_shnum:
25
e_phoff:
0x34
e_phentsize:
32
e_phnum:
5
... further output omitted
What happens when the program runs? On Solaris, ...
% hello
hello, world
% sotruss hello
hello
->
libc.so.1:*atexit(0xff3c0220,
0x20c00, 0x0)
hello
->
libc.so.1:*atexit(0x10be8,
0xff0ecbc0, 0xa7bf4)
hello
->
libc.so.1:*printf(0x10bf8,
0x0, 0x0)
hello, world
hello
->
libc.so.1:*exit(0x0,
0xffbffa14, 0xffbffa1c)
% apptrace hello
-> hello -> libc.so.1:int atexit(int
(*)() = 0xff3c0220)
<- hello -> libc.so.1:atexit()
-> hello -> libc.so.1:int atexit(int
(*)() = 0x10be0)
<- hello -> libc.so.1:atexit()
-> hello -> libc.so.1:int
printf(const
char * = 0x10bf0 "hello, world
", void * = 0xff3f0f58, ...)
hello, world
<- hello -> libc.so.1:printf() = 0xd
-> hello -> libc.so.1:exit(0x1,
0xffbffab4, 0xffbffabc) ** NR
% truss hello
execve("hello", 0xFFBFFB0C, 0xFFBFFB14) argc = 1
resolvepath("/usr/lib/ld.so.1", "/lib/ld.so.1", 1023) = 12
getcwd("/tmp",
1017)
=
0
resolvepath("/tmp/hello", "/tmp/hello", 1023) =
10
stat("/tmp/hello",
0xFFBFF8E8)
=
0
open("/var/ld/ld.config",
O_RDONLY)
Err#2
ENOENT
stat("/lib/libc.so.1",
0xFFBFF408)
=
0
resolvepath("/lib/libc.so.1", "/lib/libc.so.1", 1023) = 14
open("/lib/libc.so.1",
O_RDONLY)
=
3
mmap(0x00010000, 8192, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_ALIGN, 3, 0) = 0xFF3A0000
mmap(0x00010000, 991232, PROT_NONE,
MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0) =
0xFF280000
mmap(0xFF280000, 881573, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_TEXT, 3, 0) = 0xFF280000
mmap(0xFF368000, 29469, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_INITDATA, 3, 884736) = 0xFF368000
mmap(0xFF370000, 2592, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) = 0xFF370000
munmap(0xFF358000,
65536)
=
0
memcntl(0xFF280000, 139692, MC_ADVISE, MADV_WILLNEED, 0, 0)
= 0
close(3)
=
0
munmap(0xFF3A0000,
8192)
=
0
mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFF3A0000
getcontext(0xFFBFF5E0)
getrlimit(RLIMIT_STACK,
0xFFBFF5C0)
=
0
getpid()
=
891
[890]
setustack(0xFF3A2088)
ioctl(1, TCGETA,
0xFFBFEC4C)
=
0
fstat64(1,
0xFFBFEB68)
=
0
stat("/platform/SUNW,Sun-Blade-1500/lib/libc_psr.so.1",
0xFFBFE768) = 0
resolvepath("/platform/SUNW,Sun-Blade-1500/lib/libc_psr.so.1",
"/platform/sun4u-us3/lib/libc_psr.so.1",
1023) = 37
open("/platform/SUNW,Sun-Blade-1500/lib/libc_psr.so.1",
O_RDONLY)
= 3
mmap(0x00010000, 8192, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_ALIGN, 3, 0) = 0xFF390000
close(3)
=
0
hello, world
write(1, " h e l l o , w o r l d"..,
13) = 13
_exit(1)
What happens when the program runs? On Linux, ...
% hello
hello, world
% ltrace hello
_start(0x7fbffff9ed, 0x325c811966, 0x325c80b4e0,
0x3d52455355006f6c, 0xfefefefefefefeff <unfinished ...>
__libc_start_main(0x4004a8, 1, 0x7fbffff7d8, 0x4004c0,
0x400520
<unfinished ...>
printf("hello, world\n"hello, world
)
=
13
+++ exited (status 13) +++
% strace hello
execve("./hello", ["hello"], [/* 30 vars */]) = 0
uname({sys="Linux", node="bogus.cse.psu.edu", ...}) = 0
brk(0)
=
0x501000
mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x2a95556000
access("/etc/ld.so.preload",
R_OK)
= -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache",
O_RDONLY)
= 3
fstat(3, {st_mode=S_IFREG|0644, st_size=133511, ...}) = 0
mmap(NULL, 133511, PROT_READ, MAP_PRIVATE, 3, 0) =
0x2a95557000
close(3)
=
0
open("/lib64/tls/libc.so.6", O_RDONLY) = 3
read(3,
"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\304\241\\2\0\0\0"...,
832)
=
832
fstat(3, {st_mode=S_IFREG|0755, st_size=1622288, ...}) = 0
mmap(0x325ca00000, 2314184, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x325ca00000
mprotect(0x325cb2c000, 1085384, PROT_NONE) = 0
mmap(0x325cc2c000, 20480, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12c000) = 0x325cc2c000
mmap(0x325cc31000, 16328, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x325cc31000
close(3)
=
0
mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x2a95578000
mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x2a95579000
mprotect(0x325cc2c000, 12288, PROT_READ) = 0
mprotect(0x325c914000, 4096, PROT_READ) = 0
arch_prctl(ARCH_SET_FS, 0x2a95578b00) = 0
munmap(0x2a95557000,
133511)
=
0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4),
...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x2a95557000
write(1, "hello, world\n", 13hello, world
) = 13
exit_group(13)
=
?
What happens when the program runs? On Mac OS X, ...
% hello
hello, world
Common Unix utilities and commands [exercise - what's the
difference?]
cd – change current working directory
vi – edit a file with the vi editor
cc – compile a C program, produce an executable
file
ls – list files in a directory
Summary of tools mentioned here
tool
|
Solaris
|
Linux
|
Mac OS X
|
guess the type of a file
|
file
|
file
|
file
|
inspect a file, bytewise
|
od
|
od
hexdump |
od
hexdump |
| inspect an executable file |
elfdump
|
objdump
|
otool
|
trace system calls
|
apptrace
sotruss
truss
|
ltrace
strace
|
|
We used some terms without adequate definition or examples.
- abstract resource
- virtual resource
- actual resource, physical resource
- At this point, it's easier to deal with an example.
- The main memory in a computer system (RAM, random-access
memory) is a physical resource; let's suppose 2 gigabytes,
just to be
specific. When a process is created, the operating
system assigns
it some virtual memory;
let's
suppose 4 gigabytes, to be specific, since it really is this
much on a
32-bit system. The program acts like it has access to
the whole 4
GB, but it really doesn't; the OS puts part of the virtual
memory in
the physical memory, and part on the disk. Moreover,
every
process is treated the same way, so the OS must move parts of
the
virtual memories back and forth between physical memory and
the disk;
that's the virtual-to-physical mapping we mentioned
earlier. Many
virtual memories are mapped to one physical memory, using
essentially
the same method for all processes.
- In a sense, memory is memory, whether it's actual or
virtual,
but it's often better to assign properties to various parts of
memory. For example, the compiled program resides in the
virtual
memory of the process running the program, with the property
that this
part of the memory can't be written to by the program (for
safety), but
can be read as instructions. Data in the virtual memory
can be
written to, but not read as instructions, etc. So, these
properties help define the abstract resource of process
memory.
The mapping at this level is from properties required for
correct
program behavior to a set of permissions associated with the
virtual
memory. One abstract memory is mapped to one virtual
memory,
using information specific to each process.
- synchronous operations
- The ordering of events is predetermined; you can reliably
control or predict a sequence of events.
- For example, if A and B are events, then A must occur
before
B. This is usually interpreted as, if B is attempted,
then it
must wait for A to occur first. It could also mean, if
B is
attempted, then it cannot succeed unless A has already been
attempted,
and A succeeded; this allows for B to be attempted without
A, but in
that case it fails. This is not the same as saying, if
A happens,
then B must also happen, and later; that's the next example.
- In some cases, you can also control or predict the timing of
events, as well as their ordering.
- For example, if A happens then B must also happen, later,
and
within 10 microseconds after the time that A occurred.
- asynchronous operations
- The ordering of events is not predetermined; it cannot be
controlled or predicted.
- For example, if A and B are events, then A could happen
before
B, or B before A, or the two could happen simultaneously, or
one could
happen without the other.
- simultaneous operations
- The actual occurrence of events at the same time.
- This makes the notion of synchronous operations more
specific.
- concurrent operations
- The actual or apparent occurrence of events at the same
time.
- This generalizes the notion of asynchronous operations.
- "Concurrent programming" is the design of cooperating
components that could run simultaneously if the hardware
permits, but
might also run in sequence, without affecting the output of
the
program. This usually requires enforcing some
synchronization
rules, without requiring "tight synchronization" or
simultaneous
operation.
- CS:APP, Sec. 1.9.1, distinguishes concurrency (the concept of a
system with multiple simultaneous activities) and parallelism (the use of
concurrency
in an actual system).
- thread-level concurrency
- instruction-level parallelism
- SIMD parallelism
- wrapper function
- A (relatively) small function that accepts parameters,
checks
them, calls another function, checks the result, and doesn't
really do
much else. Primarily used to give a different interface
to the
other function, such as an abstraction to a device driver, or
improved
security. The OpenSolaris examples
open()
and bc_open()
in open.c
are trivial and tiny wrappers, while the example _endopen()
in fopen.c
is a larger wrapper. The example open_com()
in _open.c
is complicated enough that you probably should not call it a
wrapper,
but it has many of the right characteristics.
- See CS:APP Sec. 8.3 and App. A for some error-handling
wrappers.
- utility
- A program, generally provided with the operating system.
- command
- Input to a command interpreter, which then causes a program
to
be run, unless the command interpreter does the work itself.
Some definitions from the Posix Standard, 2008 edition
These are not really intended for
beginners; they are too formal, and too broad, allowing for one
specification to cover many implementations. We added some
comments [in brackets]. Some of this won't make sense until
we
get through the first few weeks of the course.
POSIX.1-2008 is simultaneously IEEE Std 1003.1™-2008 and The Open
Group
Technical Standard Base Specifications, Issue 7. More about
that
later.
- Address Space
- The memory locations that can be referenced by a process or
the
threads of a process. [see Process]
- Application
- A computer program that performs some desired
function.
[This is too general, as it doesn't distinguish application
programs
from system programs.]
- Application Program Interface (API)
- The definition of syntax and semantics for providing
computer
system services.
- Asynchronous Events
- Events that occur independently of the execution of the
application.
- Built-In Utility (or Built-In)
- A utility implemented within a shell.
- Command
- A directive to the shell to perform a particular task.
- Command Language Interpreter
- An interface that interprets sequences of text input as
commands. It may operate on an input stream or it may
interactively prompt and read commands from a terminal.
It is
possible for applications to invoke utilities through a number
of
interfaces, which are collectively considered to act as
command
interpreters. The most obvious of these are the
sh
utility and the system() function, although popen()
and the various forms of exec may also be
considered to
behave as interpreters.
- Executable File
- A regular file acceptable as a new process image file by the
equivalent of the
exec family of functions, and
thus
usable as one form of a utility. The standard utilities
described
as compilers can produce executable files, but other
unspecified
methods of producing executable files may also be provided.
The
internal format of an executable file is unspecified, but a
conforming
application cannot assume an executable file is a text file.
- File
- An object that can be written to, or read from, or
both.
A file
has certain attributes, including access permissions and
type.
File
types include regular file, character special file, block
special file,
FIFO special file, symbolic link, socket, and directory.
Other
types
of files may be supported by the implementation.
- Interactive Shell
- A processing mode of the shell that is suitable for direct
user
interaction.
- Object File
- A regular file containing the output of a compiler,
formatted
as input to a linkage editor for linking with other object
files into
an executable form. The methods of linking are
unspecified and
may involve the dynamic linking of objects at runtime.
The
internal format of an object file is unspecified, but a
conforming
application cannot assume an object file is a text file.
- Process
- An address space with one or more threads executing within
that
address space, and the required system resources for those
threads.
- Program
- A prepared sequence of instructions to the system to
accomplish
a defined task. The term "program" in POSIX.1-2008
encompasses
applications written in the Shell Command Language, complex
utility input languages (for example,
awk, lex,
sed, and so on), and high-level languages.
- Shell
- A program that interprets sequences of text input as
commands. It may operate on an input stream or it may
interactively prompt and read commands from a terminal.
- Shell, the
- The Shell Command Language Interpreter; a specific instance
of
a shell. For further information, see the
sh
utility defined in the Shell and Utilities volume of
POSIX.1-2008.
- Shell Script
- A file containing shell commands. If the file is made
executable, it can be executed by specifying its name as a
simple
command. Execution of a shell script causes a shell to
execute
the commands within the script. Alternatively, a shell
can be
requested to execute the commands in a shell script by
specifying the
name of the shell script as the operand to the
sh
utility.
- Thread
- A single flow of control within a process. [more
details,
omitted]
- Utility
- A program, excluding special built-in utilities provided as
part of the Shell Command Language, that can be called by name
from a
shell to perform a specific task, or related set of tasks.
Although we won't discuss hand-held devices in this course, here's a
quick overview of the Android software stack:
- User Applications
- Java Libraries
- Dalvik Virtual Machine
- Core C Libraries
- Linux
This clearly illustrates the idea of layered interfaces to the
system
hardware. Linux manages devices, memory and processes.
The
virtual machine supports Java programs. The Java libraries
support telephony, video, speech, graphics, network connectivity,
user
interfaces, etc.
The source code is available at http://source.android.com/
.
Last revised, 7 Jan. 2013