google ads

Sunday, May 31, 2009

Deflecting Colonial Canons and Cannons: Alternate Routes to Knowing Afghanistan

The windfall reaped by the Sethi family through their intimate commercial connections with Abdur Rahman stands in stark contrast to the more usual experience of mercantile flight from and avoidance of Afghanistan. Abdur Rahman temporarily reversed the trend of Indian capital's penetration of Afghanistan, but he could not eliminate the dependence of Afghanistan's exports on India's mass consumer markets. Geography is the primary structuring variable in the long term economic connection between Afghanistan and India, and state politics are important determinants in the precise articulation of this commercial relationship between two unequal but interdependent economic zones. Interactive social and cultural histories blend geographical constants and political fluctuations into a multidimensional holograph of market life on the frontier between Afghanistan and India. This book explored a limited set of market relationships on this frontier during the nineteenth century when colonialism was globally ascendant.

2The lens of colonialism can be adjusted, however problematically, to accommodate both macroscopic and microscopic vantage points. The oeuvres of Chris Bayly and Bernard Cohn, respectively, capture those two complimentary scopes of colonial analysis, and that argument is made stronger because each author recognizes and engages the opposite "polarity" to make their own points and positions more potent through dialogue and flexibility.1 This two-tiered vision of what can be called the local and the global is at the same time an integrated one, and as such it is perhaps the primary connection at work in the preceding pages. Other connections that are equally basic, and similarly complex in their dialectics, have been necessary to consider in order to approximate what really happened on the ground and not what is imagined to have occurred from distant vantage points during the articulation of modern Afghanistan. Colonial connections between Afghanistan and British India were addressed through relations between states and markets in their own right and in relation to one another, social communities and commodity groups independently and interactively, and through texts and money again as multifaceted but singular units of analysis as well as an analytical pairing. It has been necessary to do a bit of disentangling along the way toward making social and economic connections between states, markets, people, money, and texts. This feature of the analysis highlighted important elements of distinction, on the one hand, and continuity, on the other, which were occurring within and in many ways articulating the larger and smaller colonial connections just described.

3The connections between colonialism and capitalism are metaphorically electric and can be viewed as productively synergetic, but those same connections can also be simultaneously and literally explosive and destructive. Capitalism and colonialism each have their own conceptual turf, but when combined those two rich fields of inquiry yield a fertile terrain to cultivate a study of Afghanistan.

4Fernand Braudel's historical analysis of capitalism tracks between the micro-local and macro-global levels and has arguably yet to be surpassed. The nomadic trading tribes who were central in the foregoing analysis capture the distinctions and links between what appear in Braudel's scheme as material life and market activity, the former geared toward basic subsistence and existence, the latter involving "surplus" goods and their exchange. For Braudel capitalism arises out of market activity and generates connections between formerly unintegrated markets. The agents of those connections and the agency employed to make them correspond in many important ways to the mobile Hindkis and hundis that paired with the commercially precocious nomads to form the fluid base over which political authorities must raft and camp rather than permanently settle. Braudel's view of complementary geographic, fiscal, and social variables facilitates an understanding of the imbalanced market relationships between Kabul, Peshawar, and Qandahar. His insights about market "pulls" and polarities magnify the colonial data used here, allowing us to see distinctions and interactions between those three market settings. His global model prompts a view of our three seemingly geographically marginal markets as much more central to the functioning of larger, again separate but interactive interregional and global commercial networks.

5Braudel is also a beacon for those lost at sea when trying to navigate toward an understanding of how large-scale debt is accrued and circulated, its roles in the genesis and demise of market and political structures, and its perpetual impact on ordinary debtor folk who are not fully aware of all the variables conspiring to undermine their relative fiscal buoyancy. Braudel demarcates debt through the interactions of commodities, cash currencies, and bookkeeping practices. His consideration of financial texts and accounting practices is amplified by Jack Goody who conveys the basic importance of literacy for bureaucracy and therefore in a more complicated way for governance. While attending to literacy's state locus, Goody also demonstrates that scribal groups and textual practices transcend cultural and political barriers. Together, Braudel and Goody illuminate the cavernous debt associated with Afghanistan and help to conceptually substantiate the data-driven arguments about debt presented in this book. Among the conclusions reached here are that the origins of Afghanistan's current poverty are found in state policies and practices, the articulation of Afghanistan's debt burden transpires via state paperwork handled by certain scribal and bureaucratic classes, and that ordinary consumers experienced this state-created and state-managed debt via the marketplace where Afghan state currency was increasingly less favored and devalued in relation to surrounding exponentially stronger state monies.

6Capitalism's advance often signals the emergence of "new" social groups and the transformation of "old" social relations, but this does not mean that before capitalism time stood still for "traditional" societies who lacked a familiar form of history. Eric Wolf highlights how capitalism produces new global migrations of laboring classes associated with new production regimes and circulations of old commodities. Arjun Appadurai sees tension between consumers and state authorities emerging from new commodity flows and finds those conducting the new commercial movements to have a distinct form of knowledge transcending single market settings to geographically span full commodity trajectories from points of production to consumption. Appardurai identifies an important distinction between customary and diversionary commodity paths, the latter involving a larger reconfiguration of social and political relations along the way. For Appadurai and Wolf, global historical change is propelled by these new circulations and movements of certain key marketers, laborers, and commodities. In the markets of Kabul, Peshawar, and Qandahar these two authors allow us to see that the emergence of a far more robust bureaucracy signaled a new state fiscal regime that transformed labor and commodity traffic patterns and revised social and political relations in and between the three locales.

7Within the vast rubrics of colonialism and capitalism we have been striving for a way to manage fundamental but fundamentally complicated relationships that constitute human economic strategies, as well as other complex associations such as those between the ideological constructions of political space and the material realities and inequalities that uncooperatively represent and belie so-often hasty reasonings about Afghanistan and everything it involves. These independent but integrated explorations of capitalism and colonialism have involved histories of populations within, on the borders of, "passing through," and at varying distances outside of the territory in question. What we have been searching for is the political economy of a permeable zone characterized by multiple kinds of barriers and crossings. In other words, we have had to reckon with, on one hand boundaries, borders, and frontiers, and, on the other hand, interregional, indeed global exchange networks, trans-Eurasian commodity and cultural circuits and patterned migrations transgressing the limits of the analytical units being deployed.

CODE ACCESS SECURITY

The CLR is also burdened with the responsibility of security. An integral
part of the .NET Runtime is something called Code Access Security
(CAS), which associates a certain amount of “trust” with code, depending
on the code’s origins (the local file system, intranet, Internet, etc.).
The CLR is responsible for making sure that the code it executes stays
within its designated security boundaries. This could include such
things as reading and writing files from the user’s hard drive, making
registry entries, and so forth.
You can modify the permissions that are granted to code from a certain
location using a utility called CASPOL.EXE. You could specify, for
example, that all code originating from www.codenotes.com be granted
more privileges than other code that comes from the Internet. Examples
of CASPOL.EXE and an in-depth discussion of Code Access Security
can be found at aNET010006.

Topic: .NET Runtime Classes
In the example earlier in this chapter, all three languages used the Console.
WriteLine() method to print “Hello World” to the screen. The
.NET Runtime classes eliminate the need to master a different set of
APIs for different languages. Instead, developers need only familiarize
themselves with the appropriate Runtime classes and then call them
from the language of their choice.
The .NET Runtime includes classes for many programmatic tasks,
including data access, GUI design, messaging, and many more. It also
acts as a wrapper around the Win32 API, eliminating the need to directly
communicate with this cryptic C-style interface. The most difficult part
of using the Runtime is figuring out which class you need to accomplish
the task at hand. A complete list of the .NET Runtime classes can be
found at aNET010007.

NAMESPACES
The .NET Runtime classes are organized in hierarchical manner using
namespaces. Namespaces provide a scope (or container) in which types
are defined. All of the .NET Runtime classes, for example, can be found
in the System namespace. In the “Hello World” example we had to in-
form the compiler that the Console class could be found in the System
namespace by qualifying it (System.Console). Namespaces can also be
nested. The System.IO namespace, for example, contains a number of
classes for I/O operations, whereas the System.Collections namespace
contains classes for common data structures such as arrays.
In the Hello World example we directly addressed the namespace.
You will frequently see code that uses implicit namespace referencing to
make it more concise. Each language uses a different keyword to include
the contents of a namespace. We could have written the Hello
World program in VB.NET as follows:
'VB.NET "Hello World" Program.

Imports System
Module HelloWorld
Sub Main
'Use the .NET Runtime Console method WriteLine,
'to output "Hello World" on the screen:
Console.WriteLine("Hello World!")
End Sub
End Module
Listing 1.4 VB.NET Hello World program using namespaces
Notice that we added the Imports System line and no longer have to
qualify the Console object as System.Console. In C#, you can perform
the same action with the “using” keyword:
// C# "Hello World" Program.
// Implicit namespace referencing
using System;
public class HelloWorld {
static public void Main () {
Console.WriteLine("Hello World.");
}
}
Listing 1.5 C# Hello World program using namespaces
As you can see, implicitly referencing namespaces can save you a lot of
typing and make your code easier to read. You will use namespaces
throughout the .NET framework to:
An Introduction to the .NET Framework . 13
• Access the .NET Runtime classes
• Access custom classes authored by other developers
• Provide a namespace for your own classes, to avoid naming conflicts
with other classes and namespaces
We will use namespaces throughout this CodeNote as we develop our
own .NET components.

SIMPLE APPLICATION

In this section we look at the proverbial “Hello World” program. For the
purposes of comparison, source code for all three .NET languages
(VB.NET, C#, and managed C++) is given below. Readers might want
to consult Chapter 2 to install the .NET Framework before proceeding.

VB.NET Application
Visual Basic developers are reminded that VB.NET now includes a
command-line compiler (VBC.EXE), allowing one to develop applications
outside the Visual Basic environment. In other words, you can
write the following program in a text editor such as Notepad. VB users
will also see from this example that VB.NET has the ability to produce
console applications, something previous versions of Visual Basic were
unable to do.
'VB.NET "Hello World" Program.
Module HelloWorld
Sub Main
'Use the .NET Runtime Console method WriteLine,
'to output "Hello World" on the screen:
System.Console.WriteLine("Hello World!")
End Sub
End Module
Listing 1.1 VB.NET Hello World program

C# Application
As with the Visual Basic example, you can write this code using any text
editor. Notice that the syntax is very similar to C++ in that class definitions
and methods are encapsulated within curly braces and individual
lines of code end with semicolons.
// C# "Hello World" Program.
public class HelloWorld {
static public void Main () {
System.Console.WriteLine("Hello World!");
}
}
Listing 1.2 C# Hello World program

Managed C++ Application
Managed C++ is almost identical to normal C++. Notice that you must
use the a::b notation for namespaces, rather than the a.b notation of Visual
Basic and C#.
// Managed C++ "Hello World" Program.
// Reference the .NET Runtime Library,
// for Console Input/Output functionality.

#using
void main() {
System::Console::WriteLine("Hello World!");
}
Listing 1.3 Managed C++ Hello World program

Compiling and Running the Example
Assuming that these files were called Hello-World.vb, Hello-World.cs,
and Hello-World.cpp, respectively, .NET console applications could be
An Introduction to the .NET Framework . 9
created by invoking each language’s compiler from the command line as
shown below (alternatively, you could create VB.NET, C#, and C++
console projects and compile them from the VS.NET IDE).
• VB.NET: vbc.exe /t:exe Hello-World.vb
• C#: csc.exe /t:exe Hello-World.cs
• Managed C++: cl.exe /CLR Hello-World.cpp
The /t:exe option informs both the VB.NET and C# compilers to produce
executable files, while the /CLR switch instructs the Visual C++
compiler to produce IL code (this option is OFF by default).

Source Analysis
The most notable difference between the three programs is that the managed
C++ example must explicitly reference the .NET Runtime classes,
which is implicitly done by the VB and C# compilers. This is accomplished
by inserting the following line at the top of all managed
C++ programs: #using . C++ COM/ATL developers
will find this command very similar to the #import directive used in Visual
C++.
Syntactical differences aside, the three programs are remarkably
similar in that they all use the Runtime Console method WriteLine() to
print “Hello World” on the screen. Such uniformity is a virtue of the
.NET Runtime—all three languages use a consistent set of classes to accomplish
the same thing. The only difference lies in the way such
classes are accessed. C++ users might recognize that we had to tell the
compiler which namespace the Console class could be found in. The
concept of namespaces and their importance to the Runtime is addressed
in the .NET Runtime section of this chapter.
Topic: The Common Language Runtime
At the heart of the .NET Framework is the Common Language Runtime
(CLR). In addition to acting as a virtual machine, interpreting and executing
IL code on the fly, the CLR performs numerous other functions,
such as type safety checking, application memory isolation, memory
management, garbage collection, and crosslanguage exception handling.

THE COMMON TYPE SYSTEM
The CLR greatly simplifies crosslanguage communication through the
introduction of the Common Type System (CTS). The CTS defines all of
the basic types that can be used in the .NET Framework and the operations
that can be performed on those types. Applications can create more
complex types, but they must be built from the types defined by the
CTS.
All CTS types are classes that derive from a base class called System.
Object (this is true even for “primitive” types such as integer and
floating point variables). This means that any object executing inside the
CLR can utilize the member functions of the System.Object class. The
methods of System.Object can be found at aNET010005, but for
the purposes of illustration we will consider the Equals() method of this
class, which can be used to test two objects for equality.
Consider the following straightforward C# fragment:
int a=5;
int b=5;
if (a==b) {
System.Console.WriteLine("a is the same as b");
}
Since all types inherit from System.Object, the code could be rewritten
as:
int a=5;
int b=5;
if (a.Equals(b)) {
System.Console.WriteLine("a is the same as b");
}

AN INTRODUCTION TO THE .NET

WHAT IS .NET?
.NET is Microsoft’s new strategy for the development and deployment
of software. Depending on your interests and development background,
you may already have a number of preconceived notions regarding
.NET. As we will see throughout this CodeNote:
• .NET fundamentally changes the way applications execute under
the Windows Operating System.
• With .NET Microsoft is, in effect, abandoning its traditional
stance, one which favors compiled components, and is embracing
interpreted technology (similar, in many ways, to the Java
paradigm).
• .NET brings about significant changes to both C++ and Visual
Basic, and introduces a new language called C# (pronounced
“C sharp”).
• .NET is built from the ground up with the Internet in mind, embracing
open Internet standards such as XML and HTTP. XML
is also used throughout the framework as both a messaging instrument
and for configuration files.

These are all noteworthy features of .NET, or more accurately the .NET
Framework, which consists of the platform and tools needed to develop
and deploy .NET applications. The .NET Framework can be distilled
into the following three entities:

1. The Common Language Runtime (CLR), which is the executionenvironment for all programs in the .NET Framework. The CLR is similar to a Java Virtual Machine (VM) in that it interprets
byte code and executes it on the fly, while simultaneously
providing services such as garbage collection and exception
handling. Unlike a Java VM, which is limited to the Java language,
the CLR is accessible from any compiler that produces
Microsoft Intermediate Language (IL) code, which is similar to
Java byte code. Code that executes inside the CLR is referred to
as managed code. Code that executes outside its boundaries is
called unmanaged code.

2. The Runtime classes, which provide hundreds of prewritten services
that clients can use. The Runtime classes are the building
blocks for .NET applications. Many technologies you may have
used in the past (ADO, for example) are now accessed through
these Runtime classes, as are basic operations such as I/O. Traditionally,
every language had its own unique supporting libraries,
accessible only from that particular language. String
manipulation, for example, was afforded to VB programmers
via the Visual Basic runtime, whereas C++ programmers depended
on libraries such as STL for similar functionality. The
.NET Runtime classes remove this limitation by uniformly offering
services to any compiler that targets the CLR. Those familiar
with Java will find the Runtime classes analogous to the
Java Class Libraries.

3. Visual Studio.NET (VS.NET), which is Microsoft’s newest version
of Visual Studio. VS.NET includes VB.NET, “managed”
C++, and C#, all of which translate source code into IL code.
VB.NET and VC.NET are the new versions of Visual Basic and
Visual C++, respectively. C# is a new Microsoft language that at
first glance appears to be a hybrid of C++ and Java. .NET development
does not have to be limited to these languages, however.
Any component or program produced by an IL-aware
compiler can run within the .NET Framework. (As of this writing,
other companies have announced IL compilers for Perl,
Python, and COBOL.) VS.NET also comes with a fully Integrated
Development Environment (IDE), which we will examine
in Chapter 7. Note the VS.NET IDE now houses the
development environments for both Visual C++ and Visual Basic.

Eye contact

You must maintain eye contact with the panel, right through the interview. This shows your self-confidence and honesty.
Many interviewees while answering, tend to look away. This conveys you are concealing your own anxiety, fear and lack of confidence.
Maintaining an eye contact is a difficult process. As the circumstances in an interview are different, the value of eye contact is tremendous in making a personal impact.

Enthusiasm

The interviewer normally pays more attention if you display an enthusiasm in whatever you say.
This enthusiasm come across in the energetic way you put forward your ideas.
You should maintain a cheerful disposition throughout the interview, i.e. a pleasant countenance hold s the interviewers interest.

Entering the room

Prior to the entering the door, adjust your attire so that it falls well.
Before entering enquire by saying, “May I come in sir/madam”.
If the door was closed before you entered, make sure you shut the door behind you softly.
Face the panel and confidently say ‘Good day sir/madam’.
If the members of the interview board want to shake hands, then offer a firm grip first maintaining eye contact and a smile.
Seek permission to sit down. If the interviewers are standing, wait for them to sit down first before sitting.
An alert interviewee would diffuse the tense situation with light-hearted humor and immediately set rapport with the interviewers.

IN HR room…

What kinds of assignments might I expect the first six months on the job?
How often are performance reviews given?
Please describe the duties of the job for me.
What products (or services) are in the development stage now?
Do you have plans for expansion?
What are your growth projections for next year?
Have you cut your staff in the last three years?
Are salary adjustments geared to the cost of living or job performance?
Does your company encourage further education?
How do you feel about creativity and individuality?
Do you offer flextime?
What is the usual promotional time frame?
Does your company offer either single or dual career-track programs?
What do you like best about your job/company?
Once the probation period is completed, how much authority will I have over decisions?
Has there been much turnover in this job area?
Do you fill positions from the outside or promote from within first?
Is your company environmentally conscious? In what ways?
In what ways is a career with your company better than one with your competitors?
Is this a new position or am I replacing someone?
What is the largest single problem facing your staff (department) now?
May I talk with the last person who held this position?
What qualities are you looking for in the candidate who fills this position?
What skills are especially important for someone in this position?
What characteristics do the achievers in this company seem to share?
Who was the last person that filled this position, what made them successful at it, where are they today, and how may I contact them?


Is there a lot of team/project work?
Will I have the opportunity to work on special projects?
Where does this position fit into the organizational structure?
How much travel, if any, is involved in this position?
What is the next course of action? When should I expect to hear from you or should I contact you?

Wednesday, May 20, 2009

Synchronization: The Too Much Milk Problem

Review idea of atomic operations. Example: counting contest.
static int i;
Process A
i = 0;
while (i < 10) {
i++;
}
cout << "A wins"; Process B
i = 0;
while (i > -10) {
i--;
}
cout << "B wins";
• Variable i is shared.
• Reference and assignment are each atomic.
• Will process A or process B win?
• Will they ever finish?
• If one finishes, will the other also finish?
• Does it help A to get a head start?
Synchronization: the use of atomic operations to ensure the correct operation of cooperating processes.
The "too much milk" problem:
Person A Person B
3:00
3:05
3:10
3:15
3:20
3:25
3:30 Look in fridge. Out of milk.
Leave for store.
Arrive at store.
Leave store.
Arrive home, put milk away.



Look in fridge. Out of milk.
Leave for store.
Arrive at store.
Leave store.
Arrive home. OH NO!
What does correct mean? One of the most important things in synchronization is to figure out what you want to achieve.
Mutual exclusion: Mechanisms that ensure that only one person or process is doing certain things at one time (others are excluded). E.g. only one person goes shopping at a time.
Critical section: A section of code, or collection of operations, in which only one process may be executing at a given time. E.g. shopping. It is a large operation that we want to make "sort of" atomic.
There are many ways to achieve mutual exclusion, which we will be discussing all of this week. Most involve some sort of locking mechanism: prevent someone from doing something. For example, before shopping, leave a note on the refrigerator.
Three elements of locking:
1. Must lock before using. leave note
2. Must unlock when done. remove note
3. Must wait if locked. do not shop if note
1st attempt at computerized milk buying:
Processes A & B
1
2
3
4
5
6
7 if (NoMilk) {
if (NoNote) {
Leave Note;
Buy Milk;
Remove Note;
}
}
What happens if we leave the note at the very beginning: does this make everything work?
2nd attempt: Change meaning of note.
A buys if there is no note, B buys if there is a note. This gets rid of confusion.
Process A Process B
1
2
3
4
5
6 if (NoNote) {
if (NoMilk) {
Buy Milk;
}
Leave Note;
} if (Note) {
if (NoMilk) {
Buy Milk;
}
Remove Note;
}
• Does this work?
• How can we tell?
• When dealing with complex parallel programs, we cannot rely on our intuitions or informal reasoning. We need to prove that the programs behave correctly. What can we say about the above solution?
Suppose B goes on vacation. A will buy milk once and will not buy any more until B returns. Thus this really does not really do what we want; it is unfair, and leads to starvation.
3rd attempt: Use 2 notes:
Process A
1
2
3
4
5
6
7 Leave NoteA;
if (NoNoteB) {
if (NoMilk) {
Buy Milk;
}
}
Remove NoteA;
Process B is the same except interchange NoteA and NoteB.
What can we say about this solution?
Solution is almost correct. We just need a way to decide who will buy milk when both leave notes (somebody has to hang around to make sure that the job gets done).
4th attempt: In case of tie, A will buy milk:
Process B stays the same as before.
Process A
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Leave NoteA;
if (NoNoteB) {
if (NoMilk) {
Buy Milk;
}
} else {
while (NoteB) {
DoNothing;
}
if (NoMilk) {
Buy Milk;
}
}
Remove NoteA;
How do we know this is correct?
This solution works. But it still has two disadvantages:
• A may have to wait while B is at the store.
• While A is waiting it is consuming resources (busy-waiting).

Independent and Cooperating Processes

Chapter 6 in Operating Systems Concepts.
Independent process: one that is independent of the rest of the universe.
• Its state is not shared in any way by any other process.
• Deterministic: input state alone determines results.
• Reproducible.
• Can stop and restart with no bad effects (only time varies).
Example: program that sums the integers from 1 to i (input).
There are many different ways in which a collection of independent processes might be executed on a processor:
• Uniprogramming: a single process is run to completion before anything else can be run on the processor.
• Multiprogramming: share one processor among several processes. If no shared state, then order of dispatching is irrelevant.
• Multiprocessing: if multiprogramming works, then it should also be ok to run processes in parallel on separate processors.
o A given process runs on only one processor at a time.
o A process may run on different processors at different times (move state, assume processors are identical).
o Cannot distinguish multiprocessing from multiprogramming on a very fine grain.
How often are processes completely independent of the rest of the universe?
________________________________________
Cooperating processes:
• Machine must model the social structures of the people that use it. People cooperate, so machine must support that cooperation. Cooperation means shared state, e.g. a single file system.
• Cooperating processes are those that share state. (May or may not actually be "cooperating")
• Behavior is nondeterministic: depends on relative execution sequence and cannot be predicted a priori.
• Behavior is irreproducible.
• Example: one process writes "ABC", another writes "CBA".


When discussing concurrent processes, multiprogramming is as dangerous as multiprocessing unless you have tight control over the multiprogramming. Also bear in mind that smart I/O devices are as bad as cooperating processes (they share the memory).
Why permit processes to cooperate?
• Want to share resources:
o One computer, many users.
o One file of checking account records, many tellers.
• Want to do things faster:
o Read next block while processing current one.
o Divide job into sub-jobs, execute in parallel.
• Want to construct systems in modular fashion. (e.g. tbl | eqn | troff)
Reading: Section 2.3.1 in Tanenbaum talks about similar stuff, but uses terms a little differently.
________________________________________
Basic assumption for cooperating process systems is that the order of some operations is irrelevant; certain operations are completely independent of certain other operations. Only a few things matter:
• Example: A = 1; B = 2; has same result as B = 2; A = 1;
• Another example: A = B+1; B = 2*B cannot be re-ordered.


Race conditions: Suppose A=1 and A=2 are executed in parallel?
Atomic operations: Before we can say ANYTHING about parallel processes, we must know that some operation is atomic, i.e. that it either happens in its entirety without interruption, or not at all. Cannot be interrupted in the middle. E.g. suppose that println is atomic -- what happens in println("ABC"); println("BCA") example?
• References and assignments are atomic in almost all systems. A=B will always get a good value for B, will always set a good value for A (not necessarily true for arrays, records, or even floating-point numbers).
• In uniprocessor systems, anything between interrupts is atomic.
• If you do not have an atomic operation, you cannot make one. Fortunately, the hardware folks give us atomic ops.
• If you have any atomic operation, you can use it to generate higher-level constructs and make parallel programs work correctly. This is the approach we will take in this class.
________________________________________

Copyright © 2001, 2008 Barton P. Miller
Non-University of Wisconsin students and teachers are welcome to print these notes their personal use. Further reproduction requires permission of the author. The trap instruction that caused the entry to the kernel has a parameter that specifies which system call is being invoked. The code starting at do_call checks to see if this number is in range, and then calls the function associated with this system call number. When this function returns, the return value (stored in the eax register) is saved in the place where all the other user registers are stored. As a result, when control is transferred from the kernel back to the user process, the return value will be in the right place.
After the system call is complete, it is time to return to the user process. There are two choices at this point: (1) either return directly the the user process that made the system call or (2) go through the dispatcher to select the next process to run. ret_from_sys_call
system_call:
#
#----Save orig_eax: system call number
# used to distinguish process that entered
# kernel via syscall from one that entered
# via some other interrupt
#
pushl %eax

#
#----Save the user's registers
#
pushl %es
pushl %ds
pushl %eax
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
pushl %ecx
pushl %ebx

#
#----Set up the memory segment registers so that the kernel's
# data segment can be accessed.
#
movl $(__KERNEL_DS),%edx
movl %edx,%ds
movl %edx,%es

#
#----Load pointer to task structure in EBX. The task structure
# resides below the 8KB per-process kernel stack.
#
movl $-8192, %ebx
andl %esp, %ebx

#
#----Check to see if system call number is a valid one, then
# look-up the address of the kernel function that handles this
# system call.
#
do_call:
cmpl $(NR_syscalls),%eax
jae badsys
call *SYMBOL_NAME(sys_call_table)(,%eax,4)

# Put return value in EAX of saved user context
movl %eax,EAX(%esp)

#
#----If we can return directly to the user, then do so, else go to
# the dispatcher to select another process to run.
#
ret_from_sys_call:
cli # Block interrupts; iret effectively re-enables them
cmpl $0,need_resched(%ebx)
jne reschedule

# restore user context (including data segments)
popl %ebx
popl %ecx
popl %edx
popl %esi
popl %edi
popl %ebp
popl %eax
popl %ds
popl %es
addl $4,%esp # ignore orig_eax
iret

reschedule:
call SYMBOL_NAME(schedule)
jmp ret_from_sys_call

Entering and Exiting the Kernel

User and Kernel Addresse Spaces
In a modern operating system, each user process runs in its own address space, and the kernel operates in its protected space. At the processor level (machine code level), the main distinction between the kernel and a user process is the ability to access certain resources such as executing privileged instructions, reading or writing special registers, and accessing certain memory locations.
The separation of user process from user process insures that each processes will not disturb each other. The separation of user processes from the kernel insures that users processes will not be able to arbitrarily modify the kernel or jump into its code. It is important that processes cannot read the kernel's memory, and that it cannot directly call any function in the kernel. Allowing such operations to occur would invalidate any protection that the kernel wants to provide.
Operating systems provide a mechanism for selectively calling certain functions in the kernel. These select functions are called kernel calls or system calls, and act as gateways into the kernel. These gateways are carefully designed to provide safe functionality. They carefully check their parameters and understand how to move data from a user process into the kernel and back again. We will discuss this topic in more detail in the Memory Management section of the course.
________________________________________
The Path In and Out of the Kernel
The only way to enter the operating kernel is to generate a processor interrupt. Note the emphasis on the word "only". These interrupts come from several sources:
• I/O devices: When a device, such as a disk or network interface, completes its current operation, it notifies the operating system by generating a processor interrupt.
• Clocks and timers: Processors have timers that can be periodic (interrupting on a fixed interval) or count-down (set to complete at some specific time in the future). Periodic timers are often used to trigger scheduling decisions. For either of these types of timers, an interrupt is generated to get the operating system's attention.
• Exceptions: When an instruction performs an invalid operation, such as divide-by-zero, invalid memory address, or floating point overflow, the processor can generate an interrupt.
• Software Interrupts (Traps): Processors provide one or more instructions that will cause the processor to generate an interrupt. These instructions often have a small integer parameter. Trap instructions are most often used to implement system calls and to be inserted into a process by a debugger to stop the process at a breakpoint.
The flow of control is as follows (and illustrated below):
1. The general path goes from the executing user process to the interrupt handler. This step is like a forced function call, where the current PC and processor status are saved on a stack.
2. The interrupt handler decides what type of interrupt was generated and calls the appropriate kernel function to handle the interrupt.
3. The general run-time state of the process is saved (as on a context switch).
4. The kernel performs the appropriate operation for the system call. This step is the "real" functionality; all the steps before and after this one are mechanisms to get here from the user call and back again.
5. if the operation that was performed was trivial and fast, then the kernel returns immediately to the interrupted process. Otherwise, sometime later (it might be much later), after the operation is complete, the kernel executes its short-term scheduler (dispatcher) to pick the next process to run.
Note that one side effect of an interrupt might be to terminate the currently running process. In this case, of course, the current process will never be chosen to run next!
6. The state for the selected process is loaded into the registers and control is transferred to the process using some type of "return from interrupt" instruction.


________________________________________
The System Call Path
One of the most important uses of interrupts, and one of the least obvious when you first study about operating systems, is the system call. In your program, you might request a UNIX system to read some data from a file with a call that looks like:
rv = read(0,buff,sizeof(buff));
Somewhere, deep down in the operating system kernel, is a function that implements this read operation. For example, in Linux, the routine is called sys_read().
The path from the simple read() function call in your program to the sys_read() routine in the kernel takes you through some interesting and crucial magic. The path goes from your code to a system call stub function that contains a trap or interrupt instruction, to an interrupt handler in the kernel, to the actual kernel function. The return path is similar, with the addition of some important interactions with the process dispatcher.


________________________________________
System Call Stub Functions
The system call stub functions provide a high-level language interface to a function whose main job is to generate the software interrupt (trap) needed to get the kernel's attention. These functions are often called wrappers.
The stub functions on most operating systems do the same basic steps. While the details of implementation differ, they include the following:
1. set up the parameters,
2. trap to the kernel,
3. check the return value when the kernel returns, and
4.
1. if no error: return immediately, else
2. if there is an error: set a global error number variable (called "errno") and return a value of -1.
Below are annotated examples of this code from both the Linux (x86) and Solaris (SPARC) version of the C library. As an exercise, for the Linux and Solaris versions of the code, divide the code into the parts described above and label each part.
x86 Linux read (glibc 2.1.3)
read: push %ebx
mov 0x10(%esp,1),%edx ; put the 3 parms in registers
mov 0xc(%esp,1),%ecx
mov 0x8(%esp,1),%ebx
mov $0x3,%eax ; 3 is the syscall # for read
int $0x80 ; trap to kernel
pop %ebx
cmp $0xfffff001,%eax ; check return value
jae read_err
read_ret: ret ; return if OK.
read_err: push %ebx
call read_next ; push PC on stack
read_next: pop %ebx ; pop PC off stack to %ebx
xor %edx,%edx ; clear %edx
add $0x49a9,%ebx ; the following is a bunch of
sub %eax,%edx ; ...messy stuff that sets the
push %edx ; ...value fo the errno variable
call 0x4000dfc0 <__errno_location>
pop %ecx
pop %ebx
mov %ecx,(%eax)
or $0xffffffff,%eax ; set return value to -1
jmp read_ret ; return
SPARC Solaris 8
read: st %o0,[%sp+0x44] ! save argument 1 (fd) on stack
read_retry: mov 3,%g1 ! 3 is the syscall # for read
ta 8 ! trap to kernel
bcc read_ret ! branch if no error
cmp %o0,0x5b ! check for interrupt syscall
be,a read_retry ! ... and restart if so
ld [%sp+0x44],%o0 ! restore 1st param (fd)
mov %o7,%g1 ! save return address
call read_next ! set %o7 to PC
sethi %hi(0x1d800), %o5 ! the following is a bunch of
read_next: or %o5, 0x10, %o5 ! ...messy stuff that sets the
add %o5,%o7,%o5 ! ...value of the errno variable
mov %g1, %o7 ! ...by calling _cerror. also the
ld [%o5+0xe28],%o5 ! ...return value is set to -1
jmp %o5
nop
read_ret: retl
nop
________________________________________
Interrupt Handling and the Interrupt Vector
When an interrupt occurs, the hardware takes over and forces a control transfer that looks much like a function call. The destination of the control transfer depends on the type of interrupt. Interrupt types include things such as divide by zero, memory errors, and software interrupts (such as from the "int" instruction). The code that handles a particular type of interrupt is called (cleverly enough) an interrupt handler. As control is transferred to the appropriate interrupt handler, the process saves the PC and processor status on a special kernel stack.
The operating system sets up a table, usually called the interrupt vector, that contains one entry per type of interrupt. On the x86, this table is called the Interrupt Descriptor Table and an entry in the table is called a gate. Each vector entry contains the address of the interrupt handler for its interrupt.
In addition to branching and saving the PC and processor status, the processor will switch from a state where only certain parts of memory can be accessed and where certain instructions are prohibited (user mode) to a state where all operations are permitted (system mode).
________________________________________

Dispatching, Creating Processes

Chapter 3, Sections 3.2 and 3.3 in Operating Systems Concepts.
How does dispatcher decide which process to run next?


• Plan 0: search process table from front, run first runnable process.
o Might spend a lot of time searching.
o Weird priorities.
• Plan 1: link together the runnable processes into a queue. Dispatcher grabs first process from the queue. When processes become runnable, insert at back of queue.
• Plan 2: give each process a priority, organize the queue according to priority. Or, perhaps have multiple queues, one for each priority class.
CPU can only be doing one thing at a time: if user process is executing, dispatcher is not: OS has lost control. How does OS regain control of processor?
Internal events (things occurring within user process):
• System call.
• Error (illegal instruction, addressing violation, etc.).
• Page fault.
These are also called traps. They all cause a state switch into the OS.
External events (things occurring outside the control of the user process):
• Character typed at terminal.
• Completion of disk operation (controller is ready for more work).
• Timer: to make sure OS eventually gets control.
External events are usually called interrupts. They all cause a state switch into the OS. This means that user processes cannot directly take I/O interrupts.
________________________________________
When process is not running, its state must be saved in its process control block. What gets saved? Everything that next process could trash:
• Program counter.
• Processor status word (condition codes, etc.).
• General purpose registers.
• Floating-point registers.
• All of memory?


How do we switch contexts between the user and OS? Must be careful not to mess up process state while saving and restoring it.
Saving state: it is tricky because the the OS needs some state to execute the state saving and restoring code.
• Hand-code in assembler: avoid using registers that contain user values.
• Still have problems with things like PC and PS: cannot do either one without the other.
• All machines provide some special hardware support for saving and restoring state:
o Most modern processors: hardware does not know much about processes, it just moves PC and PS to/from the stack. OS then transfers to/from PCB, and handles rest of state itself. (We will see processor knowledge about processes when we discuss virtual memory.)
o Exotic processors, like the Intel 432: hardware did all state saving and restoring into process control block, and even dispatching.
Short cuts: as process state becomes larger and larger, saving and restoring becomes more and more expensive. Cannot afford to do full save/restore for every little interrupt.
• Sometimes different amounts are saved at different times. E.g. to handle interrupts, might save only a few registers, but to swap processes, must save everything. This is a performance optimization that can cause BIZARRE problems.
• Sometimes state can be saved and restored incrementally, e.g. in virtual memory environments.
________________________________________
Creating a process from scratch (e.g., the Windows/NT CreateProcess()):
• Load code and data into memory.
• Create (empty) call stack.
• Create and initialize process control block.
• Make process known to dispatcher.
Forking: want to make a copy of existing process (e.g., Unix).
• Make sure process to be copied is not running and has all state saved.
• Make a copy of code, data, stack.
• Copy PCB of source into new process.
• Make process known to dispatcher.
What is missing?

Introduction to Processes

Operating Systems Concepts.
With so many things happening at once in system, need some way of separating them all out cleanly. That is a process.
Important concept: decomposition. Given hard problem, chop it up into several simpler problems that can be solved separately.
What is a process?
• "An execution stream in the context of a particular process state."
• A more intuitive, but less precise, definition is just a running piece of code along with all the things that the code can affect or be affected by.
• Process state is everything that can affect, or be affected by, the process: includes code, particular data values, open files, etc.
• Execution stream is a sequence of instructions performed in a process state.
• Only one thing happens at a time within a process.
Is a process the same as a program?
Some systems allow only one process (mostly personal computers). They are called uniprogramming systems (not uniprocessing; that means only one processor). Easier to write some parts of OS, but many other things are hard to do.
________________________________________
Most systems allow more than one process. They are called multiprogramming systems.
First, have to keep track of all the processes. For each process, process control block holds:
• Execution state (saved registers, etc.)
• Scheduling information
• Accounting and other miscellaneous information.
Process table: collection of all process control blocks for all processes.
Process Control Block
Execution
State
Scheduling
Information
Accounting
and
Miscellaneous
How can several processes share one CPU? OS must make sure that processes do not interfere with each other. This means
• Making sure each gets a chance to run (fair scheduling).
• Making sure they do not modify each other's state (protection).
Dispatcher (also called Short Term Scheduler): inner-most portion of the OS that runs processes:
• Run process for a while
• Save state
• Load state of another process
• Run it ...

QUESTIONS TO ASK ABOUT OPERATINGS SYSTEMS

Or, why are studying this stuff?
Why are operating systems important?
• They consume more resources than any other program.
They may only use up a small percentage of the CPU time, but consider how many machines use the same program, all the time.
• They are the most complex programs.
They perform more functions for more users than any other program.
• They are necessary for any use of the computer.
When "the (operating) system" is down, the computer is down. Reliability and recovery from errors becomes critical.
• They are used by many users.
More hours of user time is spent dealing with the operating system. Visible changes in the operating system cause many changes to the users.
Why are operating systems difficult to create, use, and maintain?
• Size - too big for one person
Current systems have many millions lines of code. Involve 10-100 person years to build.
• Lifetime - the systems remain around longer than the programmers who wrote them.
The code is written and rewritten. Original intent is forgotten (UNIX was designed to be cute, little system - now 2 volumes this thick). Bug curve should be decreasing; but actually periodic - draw.
• Complexity - the system must do difficult things.
Deal with ugly I/O devices, multiplexing-juggling act, handle errors (hard!).
• Asynchronous - must do several things at once.
Handles interrupts, and must change what it is doing thousands of times a second - and still get work done.
• General purpose - must do many different things.
Run Doom, Java, Fortran, Lisp, Trek, Databases, Web Servers, etc. Everybody wants their stuff to run well.
________________________________________
Operating systems are an unsolved problem.
• Most do not work very well.
Crash too often, too slow, awkward to use, etc.
• Usually they do not do everything they were designed to do.
• Do not adapt to changes very well.
New devices, processors, applications.
• There are no perfect models to emulate.
________________________________________
(No, UNIX is not it! Nor is Windows!) Unlike fields like electronics where there are such models (zero distortion, flat response), any real system has (a large number of) flaws.
________________________________________

Copyright © 2001, 2002, 2008 Barton P. Miller
Non-University of Wisconsin students and teachers are welcome to print these notes their personal use. Further reproduction requires permission of the author.

VIEWS OF AN OPERATING SYSTEM

As a scheduler/allocator:
• The operating system has resources for which it is in charge. Responsible for handing them out (and later recovering them).
• Resources include CPU, memory, I/O devices, and disk space.
As a virtual machine:
• Operating system provides a "new" machine.
This machine could be the same as the underlying machine. Allows many users to believe they have an entire piece of hardware to themselves.
This could implement a different, perhaps more powerful, machine. Or just a different machine entirely. It may be useful to be able to completely simulate another machine with your current hardware. Example of upgrading to a new piece of hardware. This can get out of hand. E.g., 1401 -> 360 -> 370 -> 3081.
As a multiplexor:
• Allows sharing of resources, and provides protection from interference.
• Provides for a level of cooperation between users.
• Economic reasons: we have to take turns.
________________________________________
According to these three views, if:
• we had enough hardware to give everyone too much;
• the hardware was well designed;
• the communications problem -- how to share knowledge -- is solved;
then we would not need operating systems. My view of operating systems says that they will still be needed:
As a servant and provider of services:
• Need to provide things like in the above views, but deal with environments that are less than perfect. Help the users use the computer by:
providing commonly used subroutines;
providing access to hardware facilities;
providing higher-level "abstract" facilities;
providing an environment which is easy, pleasant, and productive to use.
This view as a provider of services fits well with our modern network view of computing, where most resources are services.
________________________________________
What are the desirable qualities of an operating system? We can discuss them in terms of: Usability, Facilities, Cost, and Adaptability.
• Usability:
o Robustness
accept all valid input without error, and gracefully handle all invalid inputs
o Consistency
E.g., if "-" means options flags in one place, it means it in another. Key idea: conventions. Concept: The Principle of Least Astonishment.
o Proportionality
Simple, cheap and frequent things are easy. Also, expensive and disastrous things (rm *) are hard.
o Forgiving
Errors can be recovered from. Reasonable error messages. Example from "rm"; UNIX vs. TOPS.
o Convenient
Not necessary to repeat things, or do awkward procedures to accomplish things. Example copying a file took a batch job.
o Powerful
Has high level facilities.
• Facilities
o Sufficient for intended use.
o Complete.
Dont leave out part of a facility. E.g., protection with
o Appropriate.
Do not use fixed-width field input from terminal.
• Costs
o Want low cost and efficient services.
o Good algorithms.
Make use of space/time tradeoffs, special hardware.
o Low overhead.
Cost of doing nothing should be low. E.g., idle time at a terminal.
o Low maintenance cost.
System should not require constant attention.
• Adaptability
o Tailored to the environment.
Support necessary activities. Do not impose unnecessary restrictions. What are the things people do most -- make them easy.
o Changeable over time.
Adapt as needs and resources change. E.g., expanding memory and new devices, or new user population.
o Extendible-Extensible
Adding new facilities and features - which look like the old ones.
________________________________________
Two main perspectives of an operating system:
• Outside - depends on your level of sophistication.
A system to compile and run Java programs
Your average introductory Computer Sciences student.
A system with many facilities - compilers, databases, file systems, system calls.
• Inside - internals, code, data structures.
This is the system programmers view of an operating system. At this level you understand not only what is provided, but how it is provided.
________________________________________
Go over class information sheet. Initial programming assignment and chapter 1 from Dinosaur book.
Explain teaching and grading philosophy (probably when doing info sheet). Emphasize "come talk to me first" view before cheating.

Computer System Structure

Computer system can be divided into four components
Hardware – provides basic computing resources
CPU, memory, I/O devices
Operating system
Controls and coordinates use of hardware among various applications and users
Application programs – define the ways in which the system resources are used to solve the computing problems of the users
Word processors, compilers, web browsers, database systems, video games
Users
People, machines, other computers

Tuesday, May 19, 2009

Pointers

C and C++ have variables that hold memory addresses. These are called pointers. Pointers are an extremely powerful programming feature, long regarded as essential to any full-strength programming language. But the power of pointers also comes at a price, and safe use of pointers turns out to be rather difficult in large programs and the source of many bugs. The most common uses of pointers are:
• Working with arrays, especially char arrays.
• For dynamic memory allocation of data structures.
• To link data structures together.
Pointers are so powerful they are dangerous. They are dangerous because they can access any memory location and a small error in their use can have mysteriously bizarre results, often showing up only later in execution or when the program is run in a different environment. It is estimated that about 50% of the bugs in production ("shrink-wrapped") software are due to pointer misuse. Consequently, some languages do not have pointers, and only have a more restricted use of memory addresses called references.

Memory addresses

Every byte in memory has an integer memory address. Addresses start at zero and go to the maximum amount of memory that the computer has. For example, in a computer that has 256 MB of RAM the bytes would be numbered 0, 1, 2, 3, 4, 5, etc (up to the power of 2 closest to 256,000,000). Instructions and data are stored in RAM when a program is running, so each instruction or data element is identified by its memory address, or the address of its first byte because many types are longer than one byte. The CPU uses these memory addresses for all operations. One of the great advantages of higher-level language is that all these addressing details are taken care of automatically by the programming language and the programmer doesn't have to worry about them. However, it can be very useful for the programmer to be able to explicitly use memory addresses as data. This data type is called a pointer.

differences between DBMS and RDBMS

What are the differences between a DBMS and a RDBMS? Well, this is a tricky one to answer. Why? First of all, there are those that would tell you that there are not any real relational database management system (RDBMS) products available, so the answer should be given in the theoretical, instead of based on real DBMS products. I find this unsatisfactory (even though it is true). The market leading DBMS products today are all SQL DBMS products. They were originally based on the relational database management model - but did not implement the model fully or completely accurately. Anyway, let me answer it based on these SQL DBMS products versus others.
First of all, the SQL DBMS allows the data to be queried based on any column in any table. You do not need to create an index or keys in order to query data (even though indexes will help with performance and primary keys are required to uniquely identify data). So, relational/SQL data is easier to query than hierarchical, CODASYL, or some other model.
Secondly, because the relational model is based on set theory its accuracy and usefulness have a basis in mathematics. Indeed, a basis in mathematics that is centuries old and proven. This is a strong reason.
Additionally, a relational database describes data in terms of its natural structure only - that is, it excludes all details having to do with machine representation.

INSTALLATION

As of this writing the NET Framework is still in beta. As such, the contents
of this chapter are subject to change. Please consult the online
reference at aNET020001 for up-to-date installation instructions.

SYSTEM REQUIREMENTS
In order to install the .NET Framework on your machine, Microsoft recommends
the following system configuration:
• Processor: Minimum Pentium II-450Mhz (Pentium III-650Mhz
recommended).
• Operating System: Windows 2000 (Server or Professional), Windows
XP, or Windows NT 4.0 Server.
• Memory: 96 MB (128 MB recommended) for Windows 2000
Professional, 192MB (256 MB recommended) for Windows
2000 server.
• Hard drive: 500MB free on the drive where the OS is installed
(usually C:\) and 2.5 Gigs free on the installation drive (where
VS.NET will be installed).

.NET DISTRIBUTION
The .NET Framework is distributed on four CDs. The first three contain
the VS.NET development tools, and the fourth contains the Windows
Component Update. The Windows Component Update will install the
core framework files (the CLR, Runtime classes) and updated versions
of system files that the Framework requires in order to run on your machine.
For information on obtaining the CDs either by mail or download,
please see www.microsoft.com/net/.

INSTALLING .NET
To install the .NET Framework, run SETUP.EXE, found on the first CD.
After a couple of minutes, you will be greeted with the screen in Figure
2.1.
Figure 2.1 VS.NET setup
As Figure 2.1 indicates, you must run the Windows Component Update
before installing VS.NET. After clicking Windows Component Update,
the setup program will analyze your machine for a few minutes to determine
which system files need to be updated. Depending on the oper-
Installation . 19
ating system and the applications that you have already installed, the
setup program may have to reboot the system several times during the
installation process. Because of this, it offers the Automatic Log On feature.
When you supply your user ID and password, the system can automatically
log on and continue the installation every time it has to reboot
the machine. Because the setup program may have to reboot the machine
as many as seven times during the installation routine, this option
can be a real timesaver. If you disable this option, you will have to log
on each time the computer reboots. (As of this writing there are some
beta issues with automatic log-on, so please consult aNET020002 for
the latest information).
After you either enable or disable Automatic Log On, the setup program
will begin the Windows Component Update. Depending on the
files it must update, this procedure can take several minutes. After the
Windows Component Update has been completed, the setup program
will prompt you for the first VS.NET CD. It will then ask you to choose
which portions of VS.NET you want installed (the IDE, MSDN documentation,
etc.).
After selecting those aspects of VS.NET that you want included,
click Install Now. (For the purposes of working with the examples in this
book, we recommend that you accept the default install options.) The
setup program will begin. Depending on the options you have selected,
installation will take anywhere from twenty to sixty minutes. After the
installation has been completed, your computer will contain all of the
necessary tools to build and deploy .NET applications.


PROGRAM LOCATIONS
The .NET setup program will append two new items to your Start
menu’s Program folder. The first item is called Microsoft .NET Framework
SDK and contains MSDN documentation and Code samples. The
second item is called Microsoft Visual Studio.NET 7.0 and contains
links to the VS.NET IDE and to another folder called Visual Studio.NET
Tools. We will build the majority of programs in this CodeNote from the
VS.NET command line, which you can access by clicking the Visual
Studio.NET Command Prompt icon shown in Figure 2.2.
Those familiar with previous versions of Visual C++ should note that
you can also bring up this command prompt by running the
vcvars32.bat file, found in the \%Program Files%1\Microsoft Visual
Studio.NET\Vc7\bin directory.
Figure 2.2 The Visual Studio.NET Command Prompt
Finally, note that many utilities we use throughout this CodeNote
(ILDASM.EXE in Chapter 1, SN.EXE in Chapter 2, etc.) are found in
the \%Program Files%\Microsoft.NET\FrameworkSDK\Bin directory. If
you use the VS.NET Command Prompt in Figure 2.2, this directory will
automatically be included in your Path variable, so you can access the
.NET Framework utilities from within any directory. However, if you
use a normal Windows command prompt, you will have to manually add
the tool directory to your path or provide relative paths to the tools you
need to use (or run the aforementioned vsvars32.bat file).

AN INTRODUCTION TO THE .NET

WHAT IS .NET?
.NET is Microsoft’s new strategy for the development and deployment
of software. Depending on your interests and development background,
you may already have a number of preconceived notions regarding
.NET. As we will see throughout this CodeNote:
• .NET fundamentally changes the way applications execute under
the Windows Operating System.
• With .NET Microsoft is, in effect, abandoning its traditional
stance, one which favors compiled components, and is embracing
interpreted technology (similar, in many ways, to the Java
paradigm).
• .NET brings about significant changes to both C++ and Visual
Basic, and introduces a new language called C# (pronounced
“C sharp”).
• .NET is built from the ground up with the Internet in mind, embracing
open Internet standards such as XML and HTTP. XML
is also used throughout the framework as both a messaging instrument
and for configuration files.

These are all noteworthy features of .NET, or more accurately the .NET
Framework, which consists of the platform and tools needed to develop
and deploy .NET applications. The .NET Framework can be distilled
into the following three entities:

1. The Common Language Runtime (CLR), which is the executionenvironment for all programs in the .NET Framework. The CLR is similar to a Java Virtual Machine (VM) in that it interprets
byte code and executes it on the fly, while simultaneously
providing services such as garbage collection and exception
handling. Unlike a Java VM, which is limited to the Java language,
the CLR is accessible from any compiler that produces
Microsoft Intermediate Language (IL) code, which is similar to
Java byte code. Code that executes inside the CLR is referred to
as managed code. Code that executes outside its boundaries is
called unmanaged code.

2. The Runtime classes, which provide hundreds of prewritten services
that clients can use. The Runtime classes are the building
blocks for .NET applications. Many technologies you may have
used in the past (ADO, for example) are now accessed through
these Runtime classes, as are basic operations such as I/O. Traditionally,
every language had its own unique supporting libraries,
accessible only from that particular language. String
manipulation, for example, was afforded to VB programmers
via the Visual Basic runtime, whereas C++ programmers depended
on libraries such as STL for similar functionality. The
.NET Runtime classes remove this limitation by uniformly offering
services to any compiler that targets the CLR. Those familiar
with Java will find the Runtime classes analogous to the
Java Class Libraries.

3. Visual Studio.NET (VS.NET), which is Microsoft’s newest version
of Visual Studio. VS.NET includes VB.NET, “managed”
C++, and C#, all of which translate source code into IL code.
VB.NET and VC.NET are the new versions of Visual Basic and
Visual C++, respectively. C# is a new Microsoft language that at
first glance appears to be a hybrid of C++ and Java. .NET development
does not have to be limited to these languages, however.
Any component or program produced by an IL-aware
compiler can run within the .NET Framework. (As of this writing,
other companies have announced IL compilers for Perl,
Python, and COBOL.) VS.NET also comes with a fully Integrated
Development Environment (IDE), which we will examine
in Chapter 7. Note the VS.NET IDE now houses the
development environments for both Visual C++ and Visual Basic.
OUTLINE OF THE BOOK
In this chapter we will examine the three fundamentals of the .NET
Framework previously listed.

Chapter 2 provides brief installation instructions. Because .NET was
still in beta release at the time of writing, these instructions may be out
of date. Readers are encouraged to consult the online instructions at
aNET010001.
One of the goals of .NET was to eliminate the versioning problems of
traditional Win32 DLLs (a problem sometimes referred to as DLL Hell).
This is realized through a new type of component in the .NET Framework
called the assembly, the subject of
Chapter 3. .NET eradicates DLL Hell from the Windows environment by enforcing the versioning
of assemblies through public key cryptography.

In Chapter 4, we will look at some of the new language features in the
.NET Framework, such as attributes, which are nonprogrammatic code
statements that can be used to influence application behavior, and delegates,
the new type-safe callback mechanism in the managed environment.
Garbage collection, a service performed by the CLR, will also be
investigated, as will reflection, the ability to ascertain type information
about an application at runtime.
The .NET Framework does not preclude the use of traditional COM
and Win32 components that have already been developed. Mechanisms
exist to allow these “unmanaged” components (those that do not run
under the auspices of the CLR) to run alongside their .NET counterparts.
Such mechanisms will be investigated in Chapter 5.
Chapter 6 looks at ADO.NET, the new data access model for the
.NET Framework. ADO.NET is a disconnected data access model,
which means that data manipulation is performed outside the context of
an open database connection. This model is especially appropriate for
web applications that are loosely coupled to their data sources. As its
name suggests, ADO.NET is an evolution of Microsoft’s ActiveX Data
Object (ADO) model.
.NET also exposes new methodologies for developing standard
Win32 applications. Windows Forms, the subject of Chapter 7, is the
new way to construct desktop GUI applications for the Windows environment.
Internet developers will also welcome Web Forms, which brings the
traditional ease and versatility of Visual Basic forms to Internet applications.
Web Forms is a feature of ASP.NET, the topic of Chapter 8.
ASP.NET is Microsoft’s new generation Active Server Page (ASP)
framework for developing robust web applications.
Chapter 9 examines Web Services and an emerging communication
An Introduction to the .NET Framework . 5
protocol called SOAP, which allow components to interact (i.e., transfer
data, perform RPC calls) via open Internet standards such as XML and
HTTP.
CORE CONCEPTS

Visual Studio.NET
Producing .NET applications and components requires a compiler that
translates source code into IL code. VS.NET, Microsoft’s new version of
Visual Studio, contains three such compilers: VB.NET, C#, and managed
C++. While a full examination of these languages is beyond the
scope of a CodeNote, each language is briefly discussed below. Code
examples throughout this book will demonstrate some of the nuances of
each language and the syntactical differences between them.
In addition to the IDE, VS.NET contains a large assortment of command
line utilities. Some of these utilities are directly incorporated into
the development environment, while others are stand-alone. We will examine
some of these utilities throughout this CodeNote.

Visual Basic.NET
VB.NET is the most recent version of Visual Basic, what was once
thought of as VB7. VB.NET is the first version of Visual Basic to support
true object-oriented inheritance, which means it has the ability to
inherit and extend the interface and behavior of any class produced by
an IL compiler. This is significant, as previous versions of Visual Basic
could only inherit from classes written in VB itself. This feature is not
really an enhancement of VB.NET but a byproduct of the language neutrality
of the CLR, which gives all IL compilers the ability to inherit
classes from one another. VB.NET also includes exception handling
constructs (try/catch) similar to those found in Java and C++.
Unfortunately, VB.NET also brings about some syntax changes that
will break compatibility with old VB source code. Procedure parameters,
for example, are now passed by value (ByVal) by default, not by
reference (ByRef). Certain syntax elements such as GoSub, IsNull, and
IsMissing have been removed from the language altogether. For a complete
list of syntax changes, see aNET010002. Clearly, a considerable
amount of effort will be required to migrate existing Visual Basic projects
to the .NET Framework.
Although not exclusive to VB.NET, most VB users will be interested
in the Windows Forms (Chapter 7) portion of this book, which investigates
the new way Win32 screens are developed in the .NET Framework.
Windows Forms completely replaces the traditional Visual Basic
Forms editor. Finally, VB.NET now ships with a command line compiler
(VBC.EXE), allowing one to write applications outside the development
environment (using NOTEPAD, for example). In the first
example in this chapter, we will investigate VB.NET’s new compiler.

Managed C++
Managed C++ is a set of extensions added to the C++ language to allow
one to produce “managed code” (code that executes under the auspices
of the CLR). The most notable extension is the introduction of “managed
types,” which shift the burden of memory management from the
C++ programmer onto the CLR. Placing the __gc extension in front of
the declaration of a class, for example, allows instances of the class to be
garbage collected by the CLR. This convenience comes at a cost, however,
as the “managed” class must adhere to the restrictions of CLR
types. It cannot, for example, inherit from two classes, even though multiple
inheritance is a feature of the C++ language.
Another extension is that of managed arrays, which allows these data
structures to be managed by the CLR. Managed exception handling is
another amendment, differing from C++ exception handling in both
syntax and behavior. Examples of managed extensions can be found at
aNET010003. Managed C++ is a part of Visual C++ .NET, which is the
only tool in the new Visual Studio suite capable of producing unmanaged
code. It is thus the only choice for producing applications that contain
both managed and unmanaged code, as is discussed in the online
article at aNET010010.

C#
C# (pronounced “C-sharp”) is a new language that Microsoft has touted
as a simplified version of C and C++. In this respect, C# is very much
like Java, eliminating some of the more complex features of C++ such as
pointers and multiple inheritance. Most of the examples in this Code-
Note are written in C# (and VB.NET), to give you a look at this new language.
Like Java and C++, C# is an object-oriented (OO) language and
contains expected OO features such as inheritance (the ability of a class
to extend another class), polymorphism (the ability to separate an interface
from its implementation), and encapsulation (the ability of objects
to hide certain methods and instance variables from other objects).
Java and C++ developers will be immediately comfortable with C#,
while the language may present some challenges for Visual Basic developers.
Even if you choose to develop in another language under the
.NET Framework, it is worthwhile to understand C#, as the majority of
MSDN .NET code is written in C#. In this sense, C# can be considered
the “intrinsic” language of the .NET Framework, as it was developed
An Introduction to the .NET Framework . 7
solely for the managed environment, as opposed to C++ and Visual
Basic, which had to evolve into their .NET manifestations.

.NET and COM
While the .NET Framework is intended to simplify many of the complexities
that existed with COM, it in no way renders COM obsolete. All
versions of Windows today remain heavily dependent on COM, and
while Microsoft’s long-term vision may be to eradicate this component
model, it is not going anywhere soon. Chapter 5 will investigate how
.NET applications can call traditional COM components using Runtime
Callable Wrappers (RCWs).

.NET and COM+
COM+ services such as transactions, object pooling, and Just-in-Time
activation can be used from the .NET Framework and are accessed
through the System.EnterpriseServices namespace. Examples of managed
code using these services can be found at aNET010004.
The .NET Runtime also implicitly uses COM+ to support some of its
services. In the Transactions section of Chapter 6, we will see how the
.NET Runtime automatically uses COM+ services behind the scenes to
provide transactional capability for managed classes.

SIMPLE APPLICATION
In this section we look at the proverbial “Hello World” program. For the
purposes of comparison, source code for all three .NET languages
(VB.NET, C#, and managed C++) is given below. Readers might want
to consult Chapter 2 to install the .NET Framework before proceeding.

VB.NET Application
Visual Basic developers are reminded that VB.NET now includes a
command-line compiler (VBC.EXE), allowing one to develop applications
outside the Visual Basic environment. In other words, you can
write the following program in a text editor such as Notepad. VB users
will also see from this example that VB.NET has the ability to produce
console applications, something previous versions of Visual Basic were
unable to do.
'VB.NET "Hello World" Program.
Module HelloWorld
Sub Main
'Use the .NET Runtime Console method WriteLine,
'to output "Hello World" on the screen:
System.Console.WriteLine("Hello World!")
End Sub
End Module
Listing 1.1 VB.NET Hello World program

C# Application
As with the Visual Basic example, you can write this code using any text
editor. Notice that the syntax is very similar to C++ in that class definitions
and methods are encapsulated within curly braces and individual
lines of code end with semicolons.
// C# "Hello World" Program.
public class HelloWorld {
static public void Main () {
System.Console.WriteLine("Hello World!");
}
}
Listing 1.2 C# Hello World program

Managed C++ Application
Managed C++ is almost identical to normal C++. Notice that you must
use the a::b notation for namespaces, rather than the a.b notation of Visual
Basic and C#.
// Managed C++ "Hello World" Program.
// Reference the .NET Runtime Library,
// for Console Input/Output functionality.

#using
void main() {
System::Console::WriteLine("Hello World!");
}
Listing 1.3 Managed C++ Hello World program

Compiling and Running the Example
Assuming that these files were called Hello-World.vb, Hello-World.cs,
and Hello-World.cpp, respectively, .NET console applications could be
An Introduction to the .NET Framework . 9
created by invoking each language’s compiler from the command line as
shown below (alternatively, you could create VB.NET, C#, and C++
console projects and compile them from the VS.NET IDE).
• VB.NET: vbc.exe /t:exe Hello-World.vb
• C#: csc.exe /t:exe Hello-World.cs
• Managed C++: cl.exe /CLR Hello-World.cpp
The /t:exe option informs both the VB.NET and C# compilers to produce
executable files, while the /CLR switch instructs the Visual C++
compiler to produce IL code (this option is OFF by default).

Source Analysis
The most notable difference between the three programs is that the managed
C++ example must explicitly reference the .NET Runtime classes,
which is implicitly done by the VB and C# compilers. This is accomplished
by inserting the following line at the top of all managed
C++ programs: #using . C++ COM/ATL developers
will find this command very similar to the #import directive used in Visual
C++.
Syntactical differences aside, the three programs are remarkably
similar in that they all use the Runtime Console method WriteLine() to
print “Hello World” on the screen. Such uniformity is a virtue of the
.NET Runtime—all three languages use a consistent set of classes to accomplish
the same thing. The only difference lies in the way such
classes are accessed. C++ users might recognize that we had to tell the
compiler which namespace the Console class could be found in. The
concept of namespaces and their importance to the Runtime is addressed
in the .NET Runtime section of this chapter.
Topic: The Common Language Runtime
At the heart of the .NET Framework is the Common Language Runtime
(CLR). In addition to acting as a virtual machine, interpreting and executing
IL code on the fly, the CLR performs numerous other functions,
such as type safety checking, application memory isolation, memory
management, garbage collection, and crosslanguage exception handling.

THE COMMON TYPE SYSTEM
The CLR greatly simplifies crosslanguage communication through the
introduction of the Common Type System (CTS). The CTS defines all of
the basic types that can be used in the .NET Framework and the operations
that can be performed on those types. Applications can create more
complex types, but they must be built from the types defined by the
CTS.
All CTS types are classes that derive from a base class called System.
Object (this is true even for “primitive” types such as integer and
floating point variables). This means that any object executing inside the
CLR can utilize the member functions of the System.Object class. The
methods of System.Object can be found at aNET010005, but for
the purposes of illustration we will consider the Equals() method of this
class, which can be used to test two objects for equality.
Consider the following straightforward C# fragment:
int a=5;
int b=5;
if (a==b) {
System.Console.WriteLine("a is the same as b");
}
Since all types inherit from System.Object, the code could be rewritten
as:
int a=5;
int b=5;
if (a.Equals(b)) {
System.Console.WriteLine("a is the same as b");
}

COMMON LANGUAGE SPECIFICATION
A subsection of the CTS called the Common Language Specification
(CLS) specifies how .NET languages share and extend one another’s libraries.
The example at the end of this chapter demonstrates how a class
written in one language can be inherited and extended by a class written
in another.
An Introduction to the .NET Framework . 11

CODE ACCESS SECURITY
The CLR is also burdened with the responsibility of security. An integral
part of the .NET Runtime is something called Code Access Security
(CAS), which associates a certain amount of “trust” with code, depending
on the code’s origins (the local file system, intranet, Internet, etc.).
The CLR is responsible for making sure that the code it executes stays
within its designated security boundaries. This could include such
things as reading and writing files from the user’s hard drive, making
registry entries, and so forth.
You can modify the permissions that are granted to code from a certain
location using a utility called CASPOL.EXE. You could specify, for
example, that all code originating from www.codenotes.com be granted
more privileges than other code that comes from the Internet. Examples
of CASPOL.EXE and an in-depth discussion of Code Access Security
can be found at aNET010006.

Topic: .NET Runtime Classes
In the example earlier in this chapter, all three languages used the Console.
WriteLine() method to print “Hello World” to the screen. The
.NET Runtime classes eliminate the need to master a different set of
APIs for different languages. Instead, developers need only familiarize
themselves with the appropriate Runtime classes and then call them
from the language of their choice.
The .NET Runtime includes classes for many programmatic tasks,
including data access, GUI design, messaging, and many more. It also
acts as a wrapper around the Win32 API, eliminating the need to directly
communicate with this cryptic C-style interface. The most difficult part
of using the Runtime is figuring out which class you need to accomplish
the task at hand. A complete list of the .NET Runtime classes can be
found at aNET010007.

NAMESPACES
The .NET Runtime classes are organized in hierarchical manner using
namespaces. Namespaces provide a scope (or container) in which types
are defined. All of the .NET Runtime classes, for example, can be found
in the System namespace. In the “Hello World” example we had to in-
form the compiler that the Console class could be found in the System
namespace by qualifying it (System.Console). Namespaces can also be
nested. The System.IO namespace, for example, contains a number of
classes for I/O operations, whereas the System.Collections namespace
contains classes for common data structures such as arrays.
In the Hello World example we directly addressed the namespace.
You will frequently see code that uses implicit namespace referencing to
make it more concise. Each language uses a different keyword to include
the contents of a namespace. We could have written the Hello
World program in VB.NET as follows:
'VB.NET "Hello World" Program.

Imports System
Module HelloWorld
Sub Main
'Use the .NET Runtime Console method WriteLine,
'to output "Hello World" on the screen:
Console.WriteLine("Hello World!")
End Sub
End Module
Listing 1.4 VB.NET Hello World program using namespaces
Notice that we added the Imports System line and no longer have to
qualify the Console object as System.Console. In C#, you can perform
the same action with the “using” keyword:
// C# "Hello World" Program.
// Implicit namespace referencing
using System;
public class HelloWorld {
static public void Main () {
Console.WriteLine("Hello World.");
}
}
Listing 1.5 C# Hello World program using namespaces
As you can see, implicitly referencing namespaces can save you a lot of
typing and make your code easier to read. You will use namespaces
throughout the .NET framework to:
An Introduction to the .NET Framework . 13
• Access the .NET Runtime classes
• Access custom classes authored by other developers
• Provide a namespace for your own classes, to avoid naming conflicts
with other classes and namespaces
We will use namespaces throughout this CodeNote as we develop our
own .NET components.

ASSIGNING A NAMESPACE
When you want to assign a particular class to a namespace, you use the
namespace keyword. For example, the following class is assigned to the
CodeNotes.HelloWorld namespace:
//C# hello world
namespace CodeNotes.HelloWorld
//rest of class
You would address any of the methods or fields of this class by using the
CodeNotes.HelloWorld prefix. This naming command is identical for all
three languages.

EXAMPLE
Sorting an array of numbers is something every programmer must do at
some point in his or her career. C and C++ programmers have traditionally
relied on the C runtime library (i.e., qsort ()) for such functionality.
The universality of the .NET Runtime means that Visual Basic
programmers can also enjoy the luxury of prewritten routines. The VB
example below uses the .NET Runtime to sort through a list of ten random
numbers. C# and C++ examples can be found at aNET010008.
'VB.NET Example that uses the .NET collection classes
'Use the System and System.Collections namespaces

Imports System
Imports System.Collections
Module SortingExample
Sub Main()
dim k as integer
dim oArray as ArrayList
dim oRandom as Random
oArray = new ArrayList()
oRandom = new Random()
'Add ten random numbers (0-99) to the list:
for k = 0 to 9
oArray.Add(oRandom.Next() mod 100)
next
oArray.Sort() 'That's it!
'Print out the sorted numbers:
for k= 0 to 9
Console.Write(oArray(k))
Console.Write(",")
next
End Sub
end module
Listing 1.6 Using the .NET Runtime classes to sort numbers
Compiling and running this program produces output similar to the following:
10,11,61,63,74,77,80,90,94,98,
The bolded portions of Listing 1.6, illustrating areas where the .NET
Runtime is being utilized, are worth more explanation.
Imports System
Imports System.Collections
The first two lines (above) inform Visual Basic that we will be using the
System and System.Collection namespaces. Recall that namespaces are
a syntactical shortcut; they save us from having to fully qualify the Runtime
class names when we reference them. The following two lines instantiate
the Runtime classes that we will use.
An Introduction to the .NET Framework . 15
oArray = new ArrayList() 'no Set !
oRandom = new Random()
The ArrayList class is like a collection; elements can be added and removed
and it will automatically resize itself. The Random class generates
the random numbers that we will sort. Note that the new Visual Basic
syntax does not require the Set keyword when instantiating classes.
for k = 0 to 9
oArray.Add(oRandom.Next() mod 100)
next
oArray.Sort() 'That's it!
The last code fragment adds ten random numbers to the list and sorts
the array. This simply involves calling the Sort() method against the
ArrayList class; the underlying operation is handled by the .NET Runtime.
As can be seen from Listing 1.6, using the .NET Runtime is simply a
matter of understanding the conventions of the classes you will be calling.
In the example above, the functionality of the program (sorting and
output) is provided by the Runtime; Visual Basic simply acts as a forum
to call it. To a large degree, your choice of .NET development language
will be a function of syntactical preference, due to the universal access
offered by the Runtime.
You may be wondering why we did not use Visual Basic’s built-in Rnd
function to generate random numbers. While we could have done this
(see the How and Why section), the general practice under the .NET
Framework is to use the Runtime classes where we can. In several instances,
VB.NET has dropped intrinsic elements of the languages as
they have been made redundant by the Runtime Classes. For details, see
aNET010009.

HOW AND WHY

Can I Still Use Intrinsic Elements (Like Rnd, Round) in My VB
Programs?
To mitigate the effort required to convert existing VB projects, Microsoft
has provided the Microsoft.VisualBasic.Compatibility runtime
DLL, which allows you to use some intrinsic elements of the Visual
Basic language. For examples, see aNET010009. However, not all intrinsic
elements are supported. See aNET10009 for details.

The .NET Runtime is a collection of classes that can be uniformly accessed
by any language capable of producing IL code. Functionality that
was traditionally provided by the language environment is now supplied
by the Runtime classes. This greatly simplifies the development process,
as one only has to familiarize oneself with a common framework, instead
of a language-dependent API. The Runtime classes are organized
using namespaces, which makes them easier to access and syntactically
more concise. We will also use namespaces when we design our own
components in the .NET Framework.

Chapter Summary
The .NET Framework consists of the platform and tools needed to develop
and deploy .NET applications. It includes an execution environment
for .NET programs (the Common Language Runtime, or CLR for
short), prewritten services that programs can access from this environment
(the .NET Runtime classes), and the development tools to produce
such programs (VS.NET).
Unlike traditional Windows applications, .NET applications are not
compiled to native machine code but are compiled to interpreted code
called Microsoft Intermediate Language (IL). IL code is the inherent
language of the CLR, which is similar to a Java VM, acting as an operating
system on the operating system, interpreting the IL code in real
time. Since IL code is interpreted, responsibilities such as memory allocation
and exception handling become property of the CLR and not the
programmer. For this reason, IL code is referred to as “managed” code,
whereas native machine code is said to be “unmanaged.”
One of the compelling reasons to develop applications in the .NET
Framework is the .NET Runtime classes. Similar to the Java Class Libraries,
these classes are the building blocks for writing .NET applications.
Throughout this book we will use the Runtime classes for more
complex operations such as database access and remote messaging. The
new .NET versions of traditional technologies such as ADO are also accessed
through the .NET Runtime, as we will see in Chapter 6.
An Introduction to the .NET Framework . 17