⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mate-manual.tex

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 TEX
📖 第 1 页 / 共 3 页
字号:
is distinct from {\tt MateTypes}, which is type-checking). Totransform a variable between in-memory and network represntations,components can invoke {\tt MTypeManager}. {\tt MTypeManager}'sinterface is a pass-through to the implementing components: acomponent that supports a given type (such as {\tt MBuffer}, whichsupports TinyScript's data buffers) wires to {\tt MTypeManager} socalls will be forwarded properly. If a VM tries to transform a typefor which there is no support, then {\tt MTypeManager} indicates thatthe type is not supported: this will generally trigger an errorcondition in the VM.\subsection{Concurrency Management: {\tt MContextSynchProxy}}\begin{figure}\centering\includegraphics[width=6in]{fig/MContextSynchProxy.jpg}\caption{{\tt MContextSynchProxy} wiring diagram.}\label{fig:mcontext-synch-proxy}\end{figure}{\tt MContextSynchProxy} is encapsulates {\tt MContextSynch} and wiresit to needed services. {\tt MContextSynch} is responsible foranalyzing code to determine when handlers can safely runconcurrently. ome instructions represent shared resources. Forexample, {\tt bpush3} and {\tt getvar4} access shared variables. Forrace free program, the VM execution engine must be aware of this andcontrol scheduling appropriately.When a component wants a context to run, it submits thecontext to {\tt MContextSynch}; based on its analyses, {\ttMContextSynch} either forwards the context on to {\tt MateEngine} forexecution, or puts it on a wait queue. If a context holding sharedresources halts, {\tt MContextSynch} has it release the resources andchecks if that allows any waiting contexts to run.{\tt MContextSynch} keeps track of shared resources through theMateBytecodeLock interface. If an instruction manages a sharedresource, then it must provide this interface. Additionally, in itsODF, it must have the optional element ``locks'' set to true.For example, let's look at OPbpush3. This instruction pushes the eightshared buffers, buffer0-7, onto the operand stack. It is not a libraryfunction; instead, it is an element of the instruction set thatTinyScript compiles to. In {\tt tscript.ldf}(Section~\ref{sec:language} describes language files in greaterdepth), it lists{\scriptsize\begin{verbatim}<OPCODE opcode="bpush3" locks=true>\end{verbatim}}Then, in OPbpush3M:{\scriptsize\begin{verbatim}module OPbpush3M {  provides interface MateBytecode;  provides interface MateBytecodeLock;}\end{verbatim}}{\tt MateBytecodeLock} has a single command:{\scriptsize\begin{verbatim}interface MateBytecodeLock {  command int16_t lockNum(uint8_t instr);}\end{verbatim}}This takes a instruction opcode and returns a unique locknumber. The idea is that certain opcodes have a lock associated withthem. {\tt bpush3}, for example, has three bits of embedded operand, forthe eight buffers. If {\tt bpush3 0} is passed to {\tt OPbpush3M.nc},then it returns the lock number for buffer zero, while {\tt bpush3 1}will return the lock number for buffer one.The full {\tt OPbpush1M.nc} logic:{\scriptsize\begin{verbatim}module OPbpush3M {  ...  provides interface MateBytecodeLock;  ...}implementation {  typedef enum {    BOMB_BUF_LOCK_3_0 = unique("MateLock"),    BOMB_BUF_LOCK_3_1 = unique("MateLock"),    ...    BOMB_BUF_LOCK_3_7 = unique("MateLock"),  } BufLockNames;  ...  command int16_t MateBytecodeLock.lockNum(uint8_t instr) {    uint8_t which = instr - OPbpush3;    switch (which) {    case 0:      return BOMB_BUF_LOCK_3_0;    case 1:      return BOMB_BUF_LOCK_3_1;    ...    case 7:      return BOMB_BUF_LOCK_3_7;    default:      return 255;    }  }  ...}\end{verbatim}}It declares eight unique lock numbers with the nesC unique function. WhenlockNum() is called, it returns the lock number associated with thecorresponding buffer. Every context has{\scriptsize\begin{verbatim}  uint8_t heldSet[(BOMB_LOCK_COUNT + 7) / 8];  uint8_t releaseSet[(BOMB_LOCK_COUNT + 7) / 8];  uint8_t acquireSet[(BOMB_LOCK_COUNT + 7) / 8];\end{verbatim}}where BOMB\_LOCK\_COUNT is defined to be uniqueCount("MateLock");\subsubsection{Synchronization Algorithms}\mate's concurrency manager is responsible for ensuring that handlersexecute atomically. Although it may allow them to run concurrently,atomicity requires that doing so should be indistinguishable fromtheir running serially. The concurrency manager maintains a bitmask ofthe shared resoures each handler uses (the {\it uses set}), and eachcontext has three bitmasks: the set of resources it holds (the {\itheld set}), the set of resources it can release (the {\it releaseset}), and the set of resources it needs to acquire (the {\it acquireset}). Initializing a context through {\ttMateContextSynch.initializeContext} sets a context's acquire set toits handler's uses set. Every time MContextSynch acquires a lock for acontext, it adds that resource to the context's held set.When new code for a handler arrives, the concurrency manager runs acontext and flow insensitive program analysis to determine the set ofshared resources that handler uses. It iterates over each instructionin the handler, using the {\tt MateBytecodeLock} interface todetermine whether an instruction requires a shared resource, updatingthe uses set of the handler. The concurrency manager maintains a lock for each shared resource;only one context may access a shared resource. When a componentsubmits a context to run through the {\ttMateContextSynch.resumeContext} command, MContextSynch checks theacquire set of the context. If every resource in the acquire set isavailable, MContextSynch atomically acquires all of the locks for thecontext and submits it to the scheduler to run. If one or more of theresources in the context's acquire set are already held, thenMContextSynch puts the context on a wait queue and sets its state to{\tt MATE\_STATE\_WAITING}.While they execute, contexts may add resources to their releaseset. This does not release those resources. When a context yields,through the {\tt MateContextSynch.yield} command, MContextSynch has itunlock each of the resources in its release set, then clears theset. MContextSynch then tests each context on the wait queue to see ifit is now runnable (the release of locks means all locks in itsacquire set are free). If a context is runnable, MContextSynch resumesit.When a context adds a resource to its release set, it may also add itto its acquire set. This means that the context will release thoseresources at the next yield point, but will not continue executionuntil it can reacquire them: it can temporarily release the resources.Currently, TinyScript does not manipulate context release sets,although it has instructions for doing so. This is an area for futurework.Because, once it starts running, the acquire set of a context isalways a subset of its release set, the set of resources a contextholds while running is montonically decreasing. A context can neverhold a resource that it did not hold when it started running. Thisensures that contexts can run deadlock-free, while the programanalysis (barring incorrect lock releases at runtime) ensuresrace-free execution.\subsection{Code Propagation: {\tt MHandlerStoreProxy}}\begin{figure}\centering\includegraphics[width=6in]{fig/MHandlerStoreProxy.jpg}\caption{{\tt MHanderStoreProxy} wiring diagram.}\label{fig:handler-store}\end{figure}The MHandlerStoreProxy component encapsulates \mate's code storage andpropagation. Figure~\ref{fig:handler-store} contains its wiringdiagram, and the component has the following signature:{\scriptsize\begin{verbatim}configuration MHandlerStoreProxy {  provides {    interface StdControl;    interface MateHandlerStore as HandlerStore[uint8_t id];  }}\end{verbatim}}Every component that has a handler should wire to HandlerStore, with aunique ID (the handler ID). VMBuilder automatically generates handlerIDs for contexts, with {\tt unique("MateHandlerID")}; if othercomponents need to register handlers, they should use the same key for{\tt unique}.{\tt MateHandlerStore} has the following signature:{\scriptsize\begin{verbatim}interface MateHandlerStore {  command result_t initializeHandler();  command MateHandlerOptions getOptions();  command MateHandlerLength getCodeLength();  command MateOpcode getOpcode(uint16_t which);  event void handlerChanged();}\end{verbatim}}It provides accessor functions for handlers, and notifies its userwhen the code for the handler has changed. Currently, MHandlerStoreallocates a static amount of memory for each handler's code (thedefault is 128 bytes), but by controlling access through an interface,this can easily be changed.MHandlerStore provides access to code at handler granularity, but\mate propagates code in terms of capsules, which contain one or morehandlers. The default implementation has a one-to-one handler-capsulemapping, but languages or compilers may require otherimplementations. For example, motlle, due to its semantics, requiresthat all handlers propagate together in a single capsule.MHandlerStore is responsible for triggering program analysis viaMContextSynchProxy when a capsule arrives. MHandlerStore sits on topof MVirus, which handles capsule propagation. The idea is that aparticular MHandlerStore implementation determines the format of thedata regions of capsules and can parse them into handlers.\begin{figure}\centering\vspace*{-.5cm}\includegraphics[width=2in]{fig/virus-states.jpg}\vspace*{-.5cm}\caption{State diagram for \mate capsule propagation.}\label{fig:prog_state}\end{figure}MVirus uses an epidemic-like approach to propagate capsules: a nodethat has newer code will broadcast it to local neighbors. The Tricklealgorithm is used to broadcast three types of data: version packets,which contain the 32-bit version numbers of all installed capsules,capsule status packets which describes fragments of a capsule that amote needs (essentially, a bitmask), and capsule fragments that areshort segments of a capsule. Figure~\ref{fig:prog_state} contains thestate diagram used by motes for code propagation. A mote can be in oneof three states: maintain (exchanging version packets), request(sending capsule status packets), or respond (sendingfragments). Nodes start in the maintain state. They enter the requeststate if they hear something that indicates someone has a newercapsule, whether it be a version, capsule status, or fragmentpacket. A requesting node returns to the maintain state once itreceives the entire capsule. A node enters the respond state if it isin the maintain state and hears that someone has an older capsule(through a version packet), or needs part of its current capsule(through a capsule status packet). These state transitions mean thatnodes prefer requesting over responding; a node will defer forwardingcapsules until it thinks it is completely up to date.Trickle's suppression operates on each type of packet (version,capsule status, and capsule fragment) individually. That is, a capsulefragment transmission will suppress all other fragment transmissions,but will not suppress version packets. This allows meta-data exchangesduring propagation: sending a fragment will not cause someone tosuppress a message saying what fragments it needs. Trickling fragmentsmeans that code propagates in a slow and controlled fashion, insteadof as quickly as possible. This is unlikely to significantly disruptany existing traffic, and prevents network overload.\subsubsection{Trickle: The Code Propagation Algorithm}The Trickle algoithm uses broadcast-based suppressions to quicklypropagate new data but minimize transmissions when nodes sharedata. The algorithm operates on an time interval $t$, which has anupper length of $t_{h}$ and a lower length of $t_{l}$.When an intervalcompletes, Trickle doubles the size of an interval, up to$t_{h}$. When it learns of new code (e.g., by overhearing a capsulefragment, version vector, or capsule status packet with a higherversion number), it shrinks the interval to $t_{l}$.Essentially, when there's nothing new to say, \mate VMs gossipinfrequently: $\tau$ is set to $\tau_{h}$. However, as soon as a motehears something new, it gossips more frequently, so those who haven'theard it yet find out. The chatter then dies down, as $\tau$ growsfrom $\tau_{l}$ to $\tau_{h}$.Trickle maintains a redundancy constant $k$ and a counter$c$. Whenever it hears a packet that would suppress its owntransmission (e.g., a capsule fragment if in the respond state), itincrements $c$. At the beginning of an interval, the algorithm resets$c$ to zero, and picks a random time in the range of$[\frac{t}{2},t]$. When it reaches that time, it transmits data if andonly if $c < k$. \section{\mate Operations}MateEngine executes programs in terms of operations. Every operationhas one or more one-byte opcodes, which map to a component thatimplements the {\tt MateBytecode} interface. An operation can haveembedded operands, which cause it to exist as more than oneopcode. For example, the {\tt bpush3} operation (which the TinyScriptlanguage uses) has three bits of embedded operand, corresponding tothe eight data buffers TinyScript makes available.The \mate tutorials describe how to write new functions, which are aparticular kind of operation: they never have embedded operands, andare generally expected to provide language-independentfunctionality. In addition to functions, operations can also beprimitives, which are the operations that compose a language. This iswhy function components have the prefix ``OP,'' such as {\tt OPid}.\subsection{Operation Component Naming Convention}Operation components have the following naming convention:{\scriptsize

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -