• No results found

Real-time system programs

N/A
N/A
Protected

Academic year: 2021

Share "Real-time system programs"

Copied!
8
0
0

Loading.... (view fulltext now)

Full text

(1)

R

eal-time system pro- grams are required to perform a multitude of different tasks at differ- ent times. The program’s task scheduler controls the time of acti- vation of each task. Often, a general- purpose real-time operating system is used. The task scheduler of most real- time operating systems assigns priori- ties to these tasks, allowing higher pri- ority tasks to preempt lower priority tasks. In most applications, data must be passed between priority levels. To ensure data integrity, a system of sem- aphores is used to control access to the common data. This can lead to a prob- lem referred to as “priority inversion,”

a condition in which a low-priority task holds up a higher priority task while the lower task is using the data.

This problem, as well as possible solu- tions, has been the focus of numerous recent articles in this magazine.

Naomi Avigdor discusses the prob- lem and gives various suggestions for dodging the issue.1For the more ana- lytically inclined, Ray Obenza pro- vides an overview of rate monotonic

analysis, a tool for guaranteeing real- time performance.2

E. Douglas Jensen, the technical director of real-time engineering at Digital Equipment Corp., states that real-time generally means “real-fast.”3 What is needed, he says, is to differen- tiate between “hard” and “soft” dead- lines for real-time computations. “Hard real-time conventionally,” Jensen writes, “is defined as deterministic in the sense that the only critical compu- tations are those with deadlines, and scheduling objective is that these com- putations must always meet their dead- lines, or the system has failed.” This would imply that that it is acceptable for some tasks to be missed and for the user to not know where the program is at all times. I don’t know about you, but I always want to know what my programs are doing. If the program’s state can always be determined (the program is deterministic), there can be no priority inversion.

Do-While Jones, possibly with tongue in cheek, went to the other extreme, extolling the advantages of interrupt-free program designs.4

by ORV BALCOM

Here is a method of task scheduling using a single interrupt that provides a deterministic approach to program timing and I/O process- ing. This approach can be implemented on any microprocessor system that can generate maskable interrupts at a fixed rate and has sufficient stack space.

44

EMBEDDED SYSTEMS PROGRAMMING JUNE 1995

Simple Task

Scheduler Prevents Priority Inversion

Nance Paternoster

< BACK

(2)

think Jones has left out a very impor- tant case between no interrupts and interrupt-driven designs. There is a program designed to use a single inter- rupt as a timing and scheduling tool.

The interrupt is generated by internal (to the CPU) or external hardware at a fixed rate. Since the interrupt is not asynchronous to the program opera- tion, the program can be deterministic and the program’s state can be known at any time. The timing of the interrupt must be based on the external asyn- chronous requirements of the system.

Since 99.99% of real-time embed- ded systems, by CPU count, have only one user and are doing only one job, I contend that none of the previous com- plications are necessary. For all but the most complex single-user systems, you must ensure that every higher priority task runs to completion before giving control to lower priority tasks. The program state can be determined at any time. As Jensen pointed out, if there is not enough CPU horsepower, the lower priority tasks may get shorted.

What is important is that the tasks, by priority, run to completion.

SINGLE INTERRUPT TASK SCHEDULER

M

ost embedded real-time

microcomputer programs require the handling of asyn- chronous inputs and outputs. This I/O must be handled in a controlled and timely manner, or elusive program bugs can occur. Real-time programs also have tasks that are synchronous to the program operation. They must be performed at fixed intervals, synchro- nized to program operation, and some- times synchronized to some external repetitive input.

This article examines a method of task scheduling using a single interrupt that provides a deterministic approach to program timing and I/O processing.

It can be implemented on any micro-

processor system that can generate maskable interrupts at a fixed rate and has sufficient stack space. While index registers are not needed, they simplify the programming of reentrant subrou- tines. The Z80 and MC68HC11 micro- processors meet these requirements.

To look at most articles and adver- tisements, you would think an embed- ded system has to have a multitasking real-time operating system. This expectation is a holdover from the days when CPUs were expensive. In those days, mainframes and minis had oper- ating systems that allowed multiple users at the same time. Since there was only one CPU, users had to share it.

Generally, these systems allocated a portion of the CPU time to each user on a rotating basis.

Instead of scheduling tasks by allo- cating various amounts of CPU time based on priorities, take the following approach. The program will run in a continuous timed loop, called the back- ground loop. During each background, different tasks are performed in order, and then the program enters a tight loop until it is time to start the back- ground again. These are the lowest pri- ority tasks. Variations in latency will not affect program performance.

Typical background tasks would per- form such functions as service a dis- play, archive data, or perform built-in test routines.

system has to have a

multitasking real-time

operating system.

(3)

Usually, some repetitive tasks must be done at a rate higher than the back- ground rate. These tasks can be syn- chronous or asynchronous. The syn- chronous tasks are called foreground tasks. The individual foreground tasks may have different activation rates, but the rates are usually multiples of each other. The foreground is often initiated by an interrupt at a fixed timed inter-

val. Typical foreground tasks are ser- vicing analog input or output, servicing a real-time control loop, or implement- ing digital filters.

The other tasks are not synchronized with the foreground and background and occur at times determined by sources outside the program. The tim- ing of their occurrence must be consid- ered random with respect to the pro-

gram timing. Figure 1 depicts the tim- ing of a single background loop of this type of program.

The traditional way to process asyn- chronous I/O is to let each service request interrupt the background and foreground process. When an asyn- chronous input or output request is detected, the CPU interrupts the pro- gram in process and vectors to the appropriate interrupt service routine.

After servicing is complete, the pro- gram returns to the program in progress. If there are two or more asyn- chronous service routines, the program requires some sort of prioritization of the routines.

As the number of different functions increases, the complexity of prioritiz- ing the interrupts also increases. This becomes especially obvious while debugging the program with an in-cir- cuit emulator. Elusive bugs caused by a second interrupt during an interrupt service routine are the bane of this approach.

There is a program design that sim- plifies the program operation and elim- inates these problems. The design uses only one CPU-generated interrupt, so prioritizing is unnecessary. Although you might not be able to meet some requirements with this design, it is applicable to most real-time systems.

First, let’s look more closely at the problems associated with processing asynchronous I/O.

INTERRUPT I/O PROCESSING

I

n an interrupt service routine, interrupts generally remain dis- abled to ensure that another inter- rupt doesn’t cause an exit from the first service routine. Consequently, the sec- ond request cannot be serviced until the first one is complete. The system requirements specify the maximum latency in servicing a given I/O request. If the length of time required for any other service routine exceeds the latency, the specification will not be met. During the initial program design, these requirements are usually met. But later, when changes are made,

46

EMBEDDED SYSTEMS PROGRAMMING JUNE 1995

Simple Task Scheduler

These diagrams show the 68HC11 and Z80 stack pointers and stack contents traced through the activation of the foreground routine and its subsequent interruption. Each hor- izontal line represents a byte. The approaches differ, since the 68HC11 automatically stacks the registers when interrupted while the Z80 has a duplicate register set that can be used during interrupt servicing.

In the following diagram for the 68HC11, PCH0, PCL0 is the return address to the inter- rupted background program. PCH1, PCL1 is the return address to the interrupt service rou- tine. PCH2, PCL2 is the return address to the foreground routine after the second interrupt.

Stack Pointer First interrupt Foreground and Return to interrupted Address initiated 2nd interrupt Background

(Hex)

10FF <—Top of Stack 10FE

10FD <— Assume 4 bytes used by Background at time of 1st interrupt

10FC . <— SP after return

10FB PCL0 <— 1st int PCL0 PCL0 from 1st int

10FA PCH0 PCH0 PCH0

10F9 IYL IYL IYL

10F8 IYH IYH IYH

10F7 IXL IXL IXL

10F6 IXH IXH IXH

10F5 ACCA ACCA ACCA

10F4 ACCB ACCB ACCB

10F3 CCR CCR CCR

10F2 PCL1 <--JSR to--> PCL1 .<—SP after return from Foreground 10F1 PCH1 Foreground PCH1

10F0

10EF <—Assume 3 bytes used by Foreground at time of 2nd interrupt

10EE . . <—SP after 2nd int

10ED PCL2 <— SP at 2nd int

10EC PCH2

10EB IYL

10EA IYH

10E9 IXL

10E8 IXH

10E7 ACCA

10E6 ACCB

10E5 CCR

10E4 . <—SP during 2nd int

68HC11 STACK POINTER MOVEMENT

(4)

it is very easy to add improvements to one service routine and affect the response time to all others. The insidi- ous part is that since the different I/O requests are asynchronous, the prob- lem will show up randomly.

It is a simple matter to see if the multiple prioritized interrupt approach will work. The interrupt service rou- tines must be prioritized, the maximum execution time for each routine deter- mined, and maximum required response latency for each routine spec-

ified. For each routine, the response latency for a given routine is the maxi- mum time required for any routine plus the sum of the time required for all rou- tines of a higher priority. This assumes that a higher priority routine can only be activated once while waiting for a lower priority routine. If not, the time needed by the routine must be multi- plied by the number of times it can be activated.

As the number of different interrupt routines increases, this procedure gets

very complicated. When there are more than a few routines, the lower priority routine latency lengthens. On a worst-case basis, it often exceeds the specification. The program designer then resorts to probability theory to say that all those higher priority interrupts could never occur at once and every- thing will work all right. Sure, until the first demonstration or qualification testing. Also, any change in the code of any service routine requires recalculat- ing the timing.

WITH POLLED I/O PROCESSING

T

here is a very simple solution for this problem that is applica- ble to most real-time systems.

If the foreground and background processes are interrupted at a suffi- ciently high rate that any asynchronous I/O latency requirement is met, all I/O can be serviced by simple polling dur- ing the single interrupt. Inherent in this approach is dividing the I/O service routines into two parts: one that is required at the higher interrupt rate and the remainder that can be executed at the foreground rate. The following is a detailed explanation of the latter approach.

First, determine the minimum laten- cy for all functions. If it is possible to operate the CPU at a fixed interrupt rate less than half this latency, the approach will probably work. For example, if the program is receiving data at 9,600 baud, it takes 1,004 ms to receive a start bit, eight data bits, no parity, and one stop bit. If it is possible to operate the CPU with an interrupt every 500 ms, received data will be available every other interrupt on the average. Data will never be available more frequently than three interrupts in a row.

Next, the individual service routines must be split into two parts. The first part, executed during each interrupt service routine, must input or output data if available. The second part, gen- erating output data or processing input data, will be scheduled at the fore- ground rate.

FIGURE 1

Foreground-background program timing.

In this diagram for the Z80, the PCH0, PCL0 and PCH2, PCL2 addresses have the same meaning as in the 68HC11 example. PCH3, PCL3 is the address of the foreground ser- vice routine and is pushed to the stack before the return from interrupt to activate the foreground.

Stack Pointer First interrupt Foreground and Return to interrupted

Address initiated 2nd interrupt Background

(Hex)

FFFF <— Top of stack FFFE

FFFD <—-Assume 6 bytes used by Background at time of 1st interrupt FFFC

FFFB

FFFA . <—SP after return

FFF9 PCH0 <— 1st int PCH0 PCH0 from 1st int to

FFF8 PCL0 PCL0 PCL0 Background

FFF7 PCH3 <-Foreground -> . Foreground Stack FFF6 PCL3 address pushed . usage, assume

FFF5 to stack followed . 3 bytes . <—SP after return FFF4 by a Return PCH2 <—SP at 2nd from 2nd int

FFF3 PCL2 interrupt

FFF2 . <— SP during 2nd interrupt

Z80 STACK POINTER MOVEMENT

(5)

The program is initialized to have a single interrupt operating at a fixed rate. The program will then enter the background loop with the interrupt enabled. When the background is inter- rupted, the code will service all asyn- chronous requirements by polling. The interrupt code also can maintain any required counters since its rate is con- stant. At the completion of the inter- rupt code, the program returns to the background. After a predetermined number of interrupts, the program exe- cutes the foreground code instead of returning to the background loop.

Interrupts must be enabled during fore- ground, so that it too can be interrupt- ed. Without this, foreground may over- run the next interrupt and violate the I/O latency requirements. Figure 2 shows this timing relationship.

An example of this approach is a program that sends and receives serial data line by line. Data is passed between the foreground and interrupt code in buffers able to hold a line of data. During each interrupt, the output code tests if the output device is busy.

If not, it will send the next character until the buffer is empty. Also, the interrupt input code checks if another input character is available. If so, it will be read and placed in local stor- age. When the program detects an end of line, it sets a flag to signal the fore- ground and moves the line from local storage to the input buffer. If moving the data takes too long, two buffers can be used and pointers to the two buffers swapped when the line is complete.

The foreground portion of the output code tests if the output buffer is empty.

When the buffer is empty and there is a new line to transmit, the foreground fills the buffer and sets a flag. The interrupt code sees the flag and begins transmitting data. The foreground por- tion of the input code monitors the flag or pointer from the interrupt code.

When a line is received, it begins pro- cessing it while the interrupt code receives the next line.

The first part of the service routines is executed each interrupt. Since the

time between interrupts is half the maximum latency for any service rou- tine, data is guaranteed to be handled in a timely manner. Obviously, the total of the interrupt portions of the ser- vice routines and any interrupt house- keeping must execute much more quickly than the period between inter- rupts. If it doesn’t, the CPU needs more horsepower.

INTERRUPT ACTIVATION

T

he interrupts must be activated at a fixed rate. The MC68HC11 has an internal counter TCNT, a 16-bit register that is continually incremented by the ‘E’ clock. There is a prescalar that can be set to 4, 8, or 16 during program initialization. The counter cannot be reset by the pro- gram, but it can be compared to one of five 16-bit compare registers. When the counter and the compare register are equal, an interrupt will be generat- ed if enabled. After each interrupt, the program must add the counts to the next interrupt to the last value in the compare register and load it to the register.

The Z80 lacks an internal counter.

External counters can consist of dis- crete devices that can be read as mem- ory, an I/O port, or the Z80’s compan- ion device, the counter/timer circuit.

The counter/timer circuit is a multiple- channel counter timer that can be used

to initiate interrupts at a fixed rate.

The period between interrupts does not have to be exact. Timing of the program will only be based on the cumulative number of interrupt activa- tions. If the period between one inter- rupt and the next is longer than normal, it will only affect the latency in I/O ser- vicing. So, it is often prudent to disable the interrupts within the foreground or background code, which should be done while moving blocks of data acquired within the interrupt routine or foreground. Disabling interrupts is only acceptable if they are disabled for a fraction of the interrupt period.

Generally, the time required to exe- cute the code within the interrupt rou- tine should be a fraction of the repeti- tion period, say 30%. If it takes too long, there will be no time for the rest of the program. Theoretically, the code could take up to two interrupt periods without disastrous results. Good design would not ever let the execution time exceed an interrupt period.

FOREGROUND ACTIVATION

A

ctivating the foreground rou- tines in place of the back- ground is not difficult but requires some planning. Remembering that the foreground will probably be interrupted, it is important that it does not share registers or RAM with the interrupt routines. The timing of the

50

EMBEDDED SYSTEMS PROGRAMMING JUNE 1995

Simple Task Scheduler

FIGURE 2

Interrupt, foreground, background program timing.

(6)

foreground activation can be scheduled by a counter in the interrupt routine.

For example, the foreground can be activated every 32 interrupts. If certain foreground tasks occur less frequently than others, it is best to activate the most frequent one directly and let the foreground code schedule the slower tasks.

The foreground is activated by a call from the interrupt routine before the normal return from interrupt. The actu- al approach differs between the Z80 and the MC68HC11. The way the machine state is saved upon entering an interrupt also differs and must be considered when calling to foreground.

Listing 1 shows the calling proce- dure for the foreground routines when using a Z80. The code segment demon- strates the portion of the interrupt ser- vice routine used to call the foreground routine. In this case, the foreground is called every eight interrupts.

The assumed hardware uses a counter to set a flip-flop to activate each interrupt. The flip-flop output is connected to pin 16, INT* of the Z80.

When the interrupt is serviced, the flip- flop is reset by writing to a port. A flag is set while in the foreground to ensure that it is not called a second time while it is executing.

When an interrupt is serviced by the Z80, only the return address is pushed to the stack. No registers are saved.

Normally, the registers (except the index registers) are swapped with the alternate registers for use during the interrupt servicing. If the index regis- ters are to be used during interrupt ser- vicing, they must be pushed to the stack. All registers must be restored before returning from the interrupt or calling the foreground.

To properly execute a return from interrupt with a Z80, a RETI instruc- tion must be executed. This will enable interrupts and return to the address on the stack that is normally the program counter location before the interrupt.

To call to the foreground routine, load the HL register with the address of the foreground entry and push it to the

stack. This is done before swapping the alternate registers. When the RETI is executed, the program counter will be set to the foreground code location.

Future interrupts will interrupt the foreground in the same manner they interrupted the background.

When in the foreground, all registers must be saved by pushing them to the stack. Any future interrupts must use the alternate registers, since the content of the registers belongs to the back- ground. To exit the foreground, restore the registers and execute a RET. The program will return to where it left off in the background. It is best to disable interrupts before starting to store or restore the registers and enable the interrupt when complete. If this is not done, an interrupt could occur and push additional data to the stack between the stored registers, which could possibly cause a problem.

Listing 2 shows the calling proce- dure for the foreground routines when using a 68HC11. The code segment demonstrates the portion of the inter- rupt service routine used to call to the foreground routine. In this case, the LISTING 1

Z80 foreground activation.

; Constants:

TRUE equ 0FFH FALSE equ 0

; Port locations ClrI equ0AAH

; The port to clear interrupt F-F

; Variable storage, based at RAM.

ForeFlag equ RAM

; Foreground lockout flag Real equ ForeFlag+1

; 2 byte free running interrupt clock

; IntReal: This is where the program

; comes from the interrupt vector.

IntReal:

EX AF,AF ; Swap the registers. dont use <IX>, <IY>

EXX

LD HL,(Real) ; Bump interrupt clock INC HL

LD (Real),HL

; The other interrupt routines would be

; done here.

; Call foreground every 8 interrupts.

LD A,(Real)

AND 7 ; Every 8 interrupts JP NZ,NotInFgd

LD HL,ForeFlag

LD A,(HL); Dont allow lock CP TRUE

JP Z,NotInFgd LD (HL),TRUE

LD HL,Forgnd ; Set new return PUSH HL ; To the stack NotInFgd:

OUT A,(ClrI) ; Reset interrupt latch EX AF,AF ; Restore registers EXX

EI RET

; NOTE: use RETI here if the hard-

; ware uses the Z80 interrupt chain

; to prioritize interrupts.

; Foreground routines.

; Called every 8 interrupts.

Forgnd:

PUSH AF PUSH BC PUSH DE PUSH HL PUSH IX

; Only store the index regs A/R PUSH IY

; Do the foreground routines here.

POP IY POP IX POP HL

POP DE POP BC

LD A,FALSE ; Release foreground LD (ForeFlag),A

POP AF RET

(7)

foreground is called every 32 inter- rupts. A flag is set to ensure that the foreground is not called a second time while it is executing.

When an MC68HC11 interrupt is serviced, the return address is pushed to the stack followed by the index reg- isters, the accumulator, and the condi- tion code register. Execution of an RTI instruction to return from the interrupt routine will restore the registers, including the condition code register that contains the interrupt enable ‘I’

bit. The program counter is restored to its position when interrupted.

To call to the foreground routines, the ‘I’ bit of the condition code register must be cleared to enable interrupts and a JSR to the foreground executed before the RTI of the interrupt routine.

Since interrupts are again enabled, the foreground may be interrupted the same as the background.

The background’s version of the registers is still on the stack, so the foreground need not save the current state of the registers. To exit the fore- ground, all that is required is a normal RTS to return from a subroutine. The program will return to the interrupt routine (with interrupts enabled) and then to the background via an RTI, restoring the registers.

ADDITIONAL CONSIDERATIONS

S

ubroutines that may be called from both the interrupt routine and the foreground or back- ground must be reentrant. This means that they may be interrupted at any time, reentered and executed to com- pletion before finishing their original activation. The implication is that the routines must not use fixed RAM vari- able locations. They must either use registers, locations on the stack, or locations referenced to the index regis- ters for variables.

If the CPU has index registers, the best solution for using common sub- routines is to allocate separate blocks of RAM for use by the interrupt rou- tine, the foreground, and the back- ground. The index registers can then be

56

EMBEDDED SYSTEMS PROGRAMMING JUNE 1995

Simple Task Scheduler

LISTING 2

68HC11 foreground activation.

; Constants:

TRUE equ 0FFH

FALSE equ 0

NumClocks equ 1024 ; Number of E clocks between interrupts

OC1F equ 80H ; Clear Timer interrupt flag

; Port locations, after moving them to page 0.

TOC1 equ 16H ; Output Compare 1 Register

TFLG1 equ 23H ; Timer Interrupt Flag Reg. 1

COPRST equ 3AH ; Arm/Reset COP Timer Circuitry

; Variable storage, based at RAM.

ForeFlag equ RAM ; Foreground lockout flag

Real equ ForeFlag+1 ; 2 byte free running interrupt clock MastErr equ Real+2 ; Location tells program about errors LastComp equ MastErr+1 ; 2 byte storage for last compare value

; IntReal: This is where the program comes from the interrupt vector.

IntReal:

JSR ResetComp ; Reset the compare register and COP

LDD Real ; Interrupt counter, 2 byte

ADDD #1 STD Real

; The other interrupt routines would be done here.

LDAA #FALSE

CMPA ForeFlag ; See if flag is False

BEQ NotInFgd ; Skip if not in foreground

; Check if program is still in foreground when it is time to enter it again. If so, it

; constitutes an error and cant be allowed to happen.

LDAA Real+1 ; Get low byte

ANDA #1FH ; Every 32 times

BNE ExitInt ; Still in foreground if not 0

LDAA #TRUE

STAA MastErr ; Show errors if here, overrun BRA ExitInt

NotInFgd:

LDAA Real+1 ; Get low byte

ANDA #1FH; Every 32 times

BNE ExitInt ; Not time for foreground yet LDAA #TRUE

STAA ForeFlag ; Going to do it

; Foreground is called here. There should ; be nothing of value in the registers.

JSR DoFgd ; Off to do the foreground, stack return LDAA #FALSE ; Return here after foreground

STAA ForeFlag ; Foreground complete ExitInt:

RTI ; Normal return, cleared I bit will be restored

; ResetComp: Reset the compare register and COP. Reset the interrupt flag bit.

(8)

used as pointers into these blocks for common subroutine variable storage.

The Z80 has three 16-bit registers and an 8-bit accumulator, which will suffice for most variables. The MC68HC11 has only a 16-bit accumu- lator, so it usually requires the use of index registers for dynamic variable storage.

SATISFACTORY RESULTS

W

e’ve examined the require- ments of program task scheduling and asynchro- nous I/O handling in a real-time sys- tem. We’ve taken a look at a tradition- al method of prioritized interrupts and a simplified method using a single interrupt. In addition, we’ve outlined approaches for implementing the sin- gle interrupt method for Z80 and MC68HC11 microprocessors.

The single interrupt method will usually give satisfactory results. The key to this approach is that a higher priority task always runs to completion before turning control over to a lower priority task. This approach is deter- ministic. It can be analyzed for correct- ness, it will never invert priorities, and it is straightforward to debug. When its performance will satisfy the system requirements, the single interrupt

method is the approach of choice.

Orv Balcom has worked in the elec- tronics industry for over 34 years, designing and programming micro- processor applications. In 1971, he founded Brown Dog Engineering, which provides custom engineering in areas of instrumentation and control systems and emphasizes the use of embedded microprocessor solutions.

Balcom received his BS in mathemat- ics from Long Beach State College. He can be reached at (310) 326-8482, or by mail at Brown Dog Engineering, Box 427, Lomita, CA 90717.

RESOURCES

1. Avigdor, Naomi, “Handling Inverted Priorities,” Embedded Systems Programming, March 1994, pp. 44.

2. Obenza, Ray, “Guaranteeing Real-Time Performance Using RMA,”

Embedded Systems Programming, May 1994, pp. 26.

3. Jensen, E. Douglas, “Eliminating the Hard/Soft Real-Time Dichotomy,”

Embedded Systems Programming, Oct.

1994, pp. 28.

4. Jones, Do-While, “Interrupt Free Design,” The Computer Applications Journal, Feb. 1994, pp. 36.

STD LastComp

STD TOC1 ; Load the new value to the counter, 2 byte

LDAA #55H ; Reset the COP

STAA COPRST LDAA #0AAH STAA COPRST LDAA #OC1F

STAA TFLG1 ; Clear interrupt flag RTS

; DoFgd: Do the foreground routines. The program should be able to use all registers.

DoFgd:

CLI ; Clear I bit to enable interrupts

; Do the foreground routines here.

RTS ; Return, end of foreground

References

Related documents

Interrupt handler switch Partition handler Virtual interrupt Interrupt Real time Virtualization layer Partitions Hardware..

The figure plots the objective space of a dual-objective optimization problem, in which the dashed line represents Pareto optimal front; the round points the common genes; and

Proof. The general method involves finding suitable test functions to put in the Rayleigh-Ritz formula to obtain an upper bound for the first nonzero eigenvalue. We first look at

Furthermore, a second-generation mindfulness-based intervention known as meditation awareness training (MAT) – which explicitly teaches emptiness meditation and accepts the

The in vitro fecal slurry incubation with FBRA showed increased organic acid production and en- hanced bifidobacteria, which indicated that FBRA had a potential as a prebiotic..

As a result of these constitutional obligations, the South African government embarked on an ambitious land reform programme was aimed at redistributing 30%

With a little over a quarter of all CTE students making up this group of CTE experimenters, analyzing their course taking patterns and subsequently their choice of most frequent