From 349331a884594a9e242231bffb03112b8943883c Mon Sep 17 00:00:00 2001 From: eb Date: Thu, 14 May 2009 18:29:26 +0000 Subject: Doc fixes. Merged eb/t367 -r11020:11025 to trunk. This changeset moves the primary doxygen configuration under the top-level docs directory. It creates a new "docs" top-level component that can be enabled/disabled using the configure --disable-docs option. At this time, the --enable-doxygen option is still required to enable the generation of the doxygen documents. I think the flag should probably be removed, and default to "yes" if we find doxygen on the path. The user can disable the doc generation using --disable-docs if desired. The doxygen config file has been modified such that doxygen is now only run on the C++ sources. No attempt is made to process the python code using doxygen. This results in a less confusing set of docs for the the C++ API. Straightening out the python docs is left for later. Many classes are currently misclassified (\ingroup ). That will probably require another day of work, that I can't get to right now. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11027 221aa14e-8319-0410-a670-987f0aec2ac5 --- docs/doxygen/other/Makefile.am | 32 ++ docs/doxygen/other/doxypy.py | 414 +++++++++++++++++ docs/doxygen/other/group_defs.dox | 95 ++++ docs/doxygen/other/main_page.dox | 5 + docs/doxygen/other/omnithread.html | 411 +++++++++++++++++ docs/doxygen/other/omnithread.pdf | Bin 0 -> 126474 bytes docs/doxygen/other/omnithread.ps | 730 ++++++++++++++++++++++++++++++ docs/doxygen/other/shared_ptr_docstub.h | 24 + docs/doxygen/other/tv-channel-frequencies | 79 ++++ docs/doxygen/other/vector_docstub.h | 16 + 10 files changed, 1806 insertions(+) create mode 100644 docs/doxygen/other/Makefile.am create mode 100755 docs/doxygen/other/doxypy.py create mode 100644 docs/doxygen/other/group_defs.dox create mode 100644 docs/doxygen/other/main_page.dox create mode 100644 docs/doxygen/other/omnithread.html create mode 100644 docs/doxygen/other/omnithread.pdf create mode 100644 docs/doxygen/other/omnithread.ps create mode 100755 docs/doxygen/other/shared_ptr_docstub.h create mode 100644 docs/doxygen/other/tv-channel-frequencies create mode 100644 docs/doxygen/other/vector_docstub.h (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/Makefile.am b/docs/doxygen/other/Makefile.am new file mode 100644 index 000000000..5e05d5d36 --- /dev/null +++ b/docs/doxygen/other/Makefile.am @@ -0,0 +1,32 @@ +# +# Copyright 2001,2004 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = \ + doxypy.py \ + group_defs.dox \ + omnithread.html \ + omnithread.pdf \ + omnithread.ps \ + shared_ptr_docstub.h \ + tv-channel-frequencies \ + vector_docstub.h diff --git a/docs/doxygen/other/doxypy.py b/docs/doxygen/other/doxypy.py new file mode 100755 index 000000000..82fdb6bea --- /dev/null +++ b/docs/doxygen/other/doxypy.py @@ -0,0 +1,414 @@ +#!/usr/bin/env python + +__applicationName__ = "doxypy" +__blurb__ = """ +doxypy is an input filter for Doxygen. It preprocesses python +files so that docstrings of classes and functions are reformatted +into Doxygen-conform documentation blocks. +""" + +__doc__ = __blurb__ + \ +""" +In order to make Doxygen preprocess files through doxypy, simply +add the following lines to your Doxyfile: + FILTER_SOURCE_FILES = YES + INPUT_FILTER = "python /path/to/doxypy.py" +""" + +__version__ = "0.4.1" +__date__ = "5th December 2008" +__website__ = "http://code.foosel.org/doxypy" + +__author__ = ( + "Philippe 'demod' Neumann (doxypy at demod dot org)", + "Gina 'foosel' Haeussge (gina at foosel dot net)" +) + +__licenseName__ = "GPL v2" +__license__ = """This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +import sys +import re + +from optparse import OptionParser, OptionGroup + +class FSM(object): + """Implements a finite state machine. + + Transitions are given as 4-tuples, consisting of an origin state, a target + state, a condition for the transition (given as a reference to a function + which gets called with a given piece of input) and a pointer to a function + to be called upon the execution of the given transition. + """ + + """ + @var transitions holds the transitions + @var current_state holds the current state + @var current_input holds the current input + @var current_transition hold the currently active transition + """ + + def __init__(self, start_state=None, transitions=[]): + self.transitions = transitions + self.current_state = start_state + self.current_input = None + self.current_transition = None + + def setStartState(self, state): + self.current_state = state + + def addTransition(self, from_state, to_state, condition, callback): + self.transitions.append([from_state, to_state, condition, callback]) + + def makeTransition(self, input): + """ Makes a transition based on the given input. + + @param input input to parse by the FSM + """ + for transition in self.transitions: + [from_state, to_state, condition, callback] = transition + if from_state == self.current_state: + match = condition(input) + if match: + self.current_state = to_state + self.current_input = input + self.current_transition = transition + if options.debug: + print >>sys.stderr, "# FSM: executing (%s -> %s) for line '%s'" % (from_state, to_state, input) + callback(match) + return + +class Doxypy(object): + def __init__(self): + string_prefixes = "[uU]?[rR]?" + + self.start_single_comment_re = re.compile("^\s*%s(''')" % string_prefixes) + self.end_single_comment_re = re.compile("(''')\s*$") + + self.start_double_comment_re = re.compile("^\s*%s(\"\"\")" % string_prefixes) + self.end_double_comment_re = re.compile("(\"\"\")\s*$") + + self.single_comment_re = re.compile("^\s*%s(''').*(''')\s*$" % string_prefixes) + self.double_comment_re = re.compile("^\s*%s(\"\"\").*(\"\"\")\s*$" % string_prefixes) + + self.defclass_re = re.compile("^(\s*)(def .+:|class .+:)") + self.empty_re = re.compile("^\s*$") + self.hashline_re = re.compile("^\s*#.*$") + self.importline_re = re.compile("^\s*(import |from .+ import)") + + self.multiline_defclass_start_re = re.compile("^(\s*)(def|class)(\s.*)?$") + self.multiline_defclass_end_re = re.compile(":\s*$") + + ## Transition list format + # ["FROM", "TO", condition, action] + transitions = [ + ### FILEHEAD + + # single line comments + ["FILEHEAD", "FILEHEAD", self.single_comment_re.search, self.appendCommentLine], + ["FILEHEAD", "FILEHEAD", self.double_comment_re.search, self.appendCommentLine], + + # multiline comments + ["FILEHEAD", "FILEHEAD_COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine], + ["FILEHEAD_COMMENT_SINGLE", "FILEHEAD", self.end_single_comment_re.search, self.appendCommentLine], + ["FILEHEAD_COMMENT_SINGLE", "FILEHEAD_COMMENT_SINGLE", self.catchall, self.appendCommentLine], + ["FILEHEAD", "FILEHEAD_COMMENT_DOUBLE", self.start_double_comment_re.search, self.appendCommentLine], + ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD", self.end_double_comment_re.search, self.appendCommentLine], + ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD_COMMENT_DOUBLE", self.catchall, self.appendCommentLine], + + # other lines + ["FILEHEAD", "FILEHEAD", self.empty_re.search, self.appendFileheadLine], + ["FILEHEAD", "FILEHEAD", self.hashline_re.search, self.appendFileheadLine], + ["FILEHEAD", "FILEHEAD", self.importline_re.search, self.appendFileheadLine], + ["FILEHEAD", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch], + ["FILEHEAD", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch], + ["FILEHEAD", "DEFCLASS_BODY", self.catchall, self.appendFileheadLine], + + ### DEFCLASS + + # single line comments + ["DEFCLASS", "DEFCLASS_BODY", self.single_comment_re.search, self.appendCommentLine], + ["DEFCLASS", "DEFCLASS_BODY", self.double_comment_re.search, self.appendCommentLine], + + # multiline comments + ["DEFCLASS", "COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine], + ["COMMENT_SINGLE", "DEFCLASS_BODY", self.end_single_comment_re.search, self.appendCommentLine], + ["COMMENT_SINGLE", "COMMENT_SINGLE", self.catchall, self.appendCommentLine], + ["DEFCLASS", "COMMENT_DOUBLE", self.start_double_comment_re.search, self.appendCommentLine], + ["COMMENT_DOUBLE", "DEFCLASS_BODY", self.end_double_comment_re.search, self.appendCommentLine], + ["COMMENT_DOUBLE", "COMMENT_DOUBLE", self.catchall, self.appendCommentLine], + + # other lines + ["DEFCLASS", "DEFCLASS", self.empty_re.search, self.appendDefclassLine], + ["DEFCLASS", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch], + ["DEFCLASS", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch], + ["DEFCLASS", "DEFCLASS_BODY", self.catchall, self.stopCommentSearch], + + ### DEFCLASS_BODY + + ["DEFCLASS_BODY", "DEFCLASS", self.defclass_re.search, self.startCommentSearch], + ["DEFCLASS_BODY", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.startCommentSearch], + ["DEFCLASS_BODY", "DEFCLASS_BODY", self.catchall, self.appendNormalLine], + + ### DEFCLASS_MULTI + ["DEFCLASS_MULTI", "DEFCLASS", self.multiline_defclass_end_re.search, self.appendDefclassLine], + ["DEFCLASS_MULTI", "DEFCLASS_MULTI", self.catchall, self.appendDefclassLine], + ] + + self.fsm = FSM("FILEHEAD", transitions) + self.outstream = sys.stdout + + self.output = [] + self.comment = [] + self.filehead = [] + self.defclass = [] + self.indent = "" + + def __closeComment(self): + """Appends any open comment block and triggering block to the output.""" + + if options.autobrief: + if len(self.comment) == 1 \ + or (len(self.comment) > 2 and self.comment[1].strip() == ''): + self.comment[0] = self.__docstringSummaryToBrief(self.comment[0]) + + if self.comment: + block = self.makeCommentBlock() + self.output.extend(block) + + if self.defclass: + self.output.extend(self.defclass) + + def __docstringSummaryToBrief(self, line): + """Adds \\brief to the docstrings summary line. + + A \\brief is prepended, provided no other doxygen command is at the + start of the line. + """ + stripped = line.strip() + if stripped and not stripped[0] in ('@', '\\'): + return "\\brief " + line + else: + return line + + def __flushBuffer(self): + """Flushes the current outputbuffer to the outstream.""" + if self.output: + try: + if options.debug: + print >>sys.stderr, "# OUTPUT: ", self.output + print >>self.outstream, "\n".join(self.output) + self.outstream.flush() + except IOError: + # Fix for FS#33. Catches "broken pipe" when doxygen closes + # stdout prematurely upon usage of INPUT_FILTER, INLINE_SOURCES + # and FILTER_SOURCE_FILES. + pass + self.output = [] + + def catchall(self, input): + """The catchall-condition, always returns true.""" + return True + + def resetCommentSearch(self, match): + """Restarts a new comment search for a different triggering line. + + Closes the current commentblock and starts a new comment search. + """ + if options.debug: + print >>sys.stderr, "# CALLBACK: resetCommentSearch" + self.__closeComment() + self.startCommentSearch(match) + + def startCommentSearch(self, match): + """Starts a new comment search. + + Saves the triggering line, resets the current comment and saves + the current indentation. + """ + if options.debug: + print >>sys.stderr, "# CALLBACK: startCommentSearch" + self.defclass = [self.fsm.current_input] + self.comment = [] + self.indent = match.group(1) + + def stopCommentSearch(self, match): + """Stops a comment search. + + Closes the current commentblock, resets the triggering line and + appends the current line to the output. + """ + if options.debug: + print >>sys.stderr, "# CALLBACK: stopCommentSearch" + self.__closeComment() + + self.defclass = [] + self.output.append(self.fsm.current_input) + + def appendFileheadLine(self, match): + """Appends a line in the FILEHEAD state. + + Closes the open comment block, resets it and appends the current line. + """ + if options.debug: + print >>sys.stderr, "# CALLBACK: appendFileheadLine" + self.__closeComment() + self.comment = [] + self.output.append(self.fsm.current_input) + + def appendCommentLine(self, match): + """Appends a comment line. + + The comment delimiter is removed from multiline start and ends as + well as singleline comments. + """ + if options.debug: + print >>sys.stderr, "# CALLBACK: appendCommentLine" + (from_state, to_state, condition, callback) = self.fsm.current_transition + + # single line comment + if (from_state == "DEFCLASS" and to_state == "DEFCLASS_BODY") \ + or (from_state == "FILEHEAD" and to_state == "FILEHEAD"): + # remove comment delimiter from begin and end of the line + activeCommentDelim = match.group(1) + line = self.fsm.current_input + self.comment.append(line[line.find(activeCommentDelim)+len(activeCommentDelim):line.rfind(activeCommentDelim)]) + + if (to_state == "DEFCLASS_BODY"): + self.__closeComment() + self.defclass = [] + # multiline start + elif from_state == "DEFCLASS" or from_state == "FILEHEAD": + # remove comment delimiter from begin of the line + activeCommentDelim = match.group(1) + line = self.fsm.current_input + self.comment.append(line[line.find(activeCommentDelim)+len(activeCommentDelim):]) + # multiline end + elif to_state == "DEFCLASS_BODY" or to_state == "FILEHEAD": + # remove comment delimiter from end of the line + activeCommentDelim = match.group(1) + line = self.fsm.current_input + self.comment.append(line[0:line.rfind(activeCommentDelim)]) + if (to_state == "DEFCLASS_BODY"): + self.__closeComment() + self.defclass = [] + # in multiline comment + else: + # just append the comment line + self.comment.append(self.fsm.current_input) + + def appendNormalLine(self, match): + """Appends a line to the output.""" + if options.debug: + print >>sys.stderr, "# CALLBACK: appendNormalLine" + self.output.append(self.fsm.current_input) + + def appendDefclassLine(self, match): + """Appends a line to the triggering block.""" + if options.debug: + print >>sys.stderr, "# CALLBACK: appendDefclassLine" + self.defclass.append(self.fsm.current_input) + + def makeCommentBlock(self): + """Indents the current comment block with respect to the current + indentation level. + + @returns a list of indented comment lines + """ + doxyStart = "##" + commentLines = self.comment + + commentLines = map(lambda x: "%s# %s" % (self.indent, x), commentLines) + l = [self.indent + doxyStart] + l.extend(commentLines) + + return l + + def parse(self, input): + """Parses a python file given as input string and returns the doxygen- + compatible representation. + + @param input the python code to parse + @returns the modified python code + """ + lines = input.split("\n") + + for line in lines: + self.fsm.makeTransition(line) + + if self.fsm.current_state == "DEFCLASS": + self.__closeComment() + + return "\n".join(self.output) + + def parseFile(self, filename): + """Parses a python file given as input string and returns the doxygen- + compatible representation. + + @param input the python code to parse + @returns the modified python code + """ + f = open(filename, 'r') + + for line in f: + self.parseLine(line.rstrip('\r\n')) + if self.fsm.current_state == "DEFCLASS": + self.__closeComment() + self.__flushBuffer() + f.close() + + def parseLine(self, line): + """Parse one line of python and flush the resulting output to the + outstream. + + @param line the python code line to parse + """ + self.fsm.makeTransition(line) + self.__flushBuffer() + +def optParse(): + """Parses commandline options.""" + parser = OptionParser(prog=__applicationName__, version="%prog " + __version__) + + parser.set_usage("%prog [options] filename") + parser.add_option("--autobrief", + action="store_true", dest="autobrief", + help="use the docstring summary line as \\brief description" + ) + parser.add_option("--debug", + action="store_true", dest="debug", + help="enable debug output on stderr" + ) + + ## parse options + global options + (options, filename) = parser.parse_args() + + if not filename: + print >>sys.stderr, "No filename given." + sys.exit(-1) + + return filename[0] + +def main(): + """Starts the parser on the file given by the filename as the first + argument on the commandline. + """ + filename = optParse() + fsm = Doxypy() + fsm.parseFile(filename) + +if __name__ == "__main__": + main() diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox new file mode 100644 index 000000000..7373236ce --- /dev/null +++ b/docs/doxygen/other/group_defs.dox @@ -0,0 +1,95 @@ +/*! + * \defgroup block Signal Processing Blocks + * These are the signal processing blocks... + * @{ + */ + +/*! + * \defgroup source Signal Sources + * signal sources docs... + */ + +/*! + * \defgroup sink Signal Sinks + * docs for sinks... + */ + +/*! + * \defgroup filter Filters + */ + +/*! + * \defgroup converter Type Conversions + */ + +/*! + * \defgroup level Signal Level Control + */ + +/*! + * \defgroup clock Signal Clock Synchronization + */ + +/*! + * \defgroup dft Fourier Transformation + */ + +/*! + * \defgroup synch Synchronization + */ + +/*! + * \defgroup packet Packetization + */ + +/*! + * \defgroup logic Logical + */ + +/*! @} */ + +/*! \defgroup filter_design Digital Filter Design */ +/*! \defgroup graphical Graphical Utilities */ +/*! \defgroup encdec Voice Encoders and Decoders */ +/*! \defgroup coding Information Coding and Decoding */ +/*! \defgroup modulation Signal Modulation */ +/*! \defgroup demodulation Signal Demodulation */ +/*! \defgroup flow Samples Flow Control */ + +/*! \defgroup math Mathmatics */ +/*! \defgroup tools Tools */ +/*! \defgroup misc Miscellaneous */ +/*! \defgroup internal Implementation Details */ + +/*! \defgroup base Misc Common Base Classes */ +/*! + * \defgroup applications Applications + * These are some applications build using gnuradio... + * @{ + */ + +/*! + * \defgroup atsc ATSC + * ATSC Applications... + */ + +/*! + * \defgroup radar Radar + * Radar Applications... + */ + +/*! + * \defgroup pager Pager + * Pager Applications + */ + +/*! + * \defgroup sounder Sounder + * Channel Sounder + */ + +/*! @} */ + +/*! \defgroup usrp USRP */ +/*! \defgroup usrp2 USRP2 */ +/*! \defgroup hardware Hardware */ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox new file mode 100644 index 000000000..5c37905fa --- /dev/null +++ b/docs/doxygen/other/main_page.dox @@ -0,0 +1,5 @@ +/*! \mainpage + +Welcome to GNU Radio! + +*/ diff --git a/docs/doxygen/other/omnithread.html b/docs/doxygen/other/omnithread.html new file mode 100644 index 000000000..5682d1d0b --- /dev/null +++ b/docs/doxygen/other/omnithread.html @@ -0,0 +1,411 @@ + + +The OMNI Thread Abstraction + + + + + + + + + + + + +

The OMNI Thread Abstraction

+ +

Tristan Richardson
+AT&T Laboratories Cambridge
+

+ +

Revised November 2001

+ + +

1  Introduction

+ +The OMNI thread abstraction is designed to provide a common set of +thread operations for use in programs written in C++. Programs +written using the abstraction should be much easier to port between +different architectures with different underlying threads primitives.
+
+The programming interface is designed to be similar to the C language +interface to POSIX threads (IEEE draft standard 1003.1c --- previously +1003.4a, often known as ``pthreads'' [POSIX94]).
+
+Much of the abstraction consists of simple C++ object wrappers around +pthread calls. However for some features such as thread-specific +data, a better interface can be offered because of the use of C++.
+
+Some of the more complex features of pthreads are not supported +because of the difficulty of ensuring the same features can be offered +on top of other thread systems. Such features include thread +cancellation and complex scheduling control (though simple thread +priorities are supported).
+
+The abstraction layer is currently implemented for the following +architectures / thread systems: + +See the omnithread.h header file for full details of the API. +The descriptions below assume you have some previous knowledge of +threads, mutexes, condition variables and semaphores. Also refer to +other documentation ([Birrell89], [POSIX94]) for further +explanation of these ideas (particularly condition variables, the use +of which may not be particularly intuitive when first encountered).
+
+ + +

2  Synchronisation objects

+ +Synchronisation objects are used to synchronise threads within the +same process. There is no inter-process synchronisation provided. +The synchronisation objects provided are mutexes, condition variables +and counting semaphores.
+
+ + +

2.1  Mutex

+ +An object of type omni_mutex is used for mutual exclusion. +It provides two operations, lock() and unlock(). +The alternative names acquire() and release() can be +used if preferred. Behaviour is undefined when a thread attempts to +lock the same mutex again or when a mutex is locked by one thread and +unlocked by a different thread.
+
+ + +

2.2  Condition Variable

+ +A condition variable is represented by an omni_condition and +is used for signalling between threads. A call to wait() +causes a thread to wait on the condition variable. A call to +signal() wakes up at least one thread if any are waiting. A +call to broadcast() wakes up all threads waiting on the +condition variable.
+
+When constructed, a pointer to an omni_mutex must be given. +A condition variable wait() has an implicit mutex +unlock() and lock() around it. The link between +condition variable and mutex lasts for the lifetime of the condition +variable (unlike pthreads where the link is only for the duration of +the wait). The same mutex may be used with several condition +variables.
+
+A wait with a timeout can be achieved by calling +timed_wait(). This is given an absolute time to wait until. +The routine omni_thread::get_time() can be used to turn a +relative time into an absolute time. timed_wait() returns +true if the condition was signalled, false if the +time expired before the condition variable was signalled.
+
+ + +

2.3  Counting semaphores

+ +An omni_semaphore is a counting semaphore. When created it +is given an initial unsigned integer value. When wait() is +called, the value is decremented if non-zero. If the value is zero +then the thread blocks instead. When post() is called, if +any threads are blocked in wait(), exactly one thread is +woken. If no threads were blocked then the value of the semaphore is +incremented.
+
+If a thread calls try_wait(), then the thread won't block if +the semaphore's value is 0, returning false instead.
+
+There is no way of querying the value of the semaphore.
+
+ + +

3  Thread object

+ +A thread is represented by an omni_thread object. There are +broadly two different ways in which it can be used.
+
+The first way is simply to create an omni_thread object, +giving a particular function which the thread should execute. This is +like the POSIX (or any other) C language interface.
+
+The second method of use is to create a new class which inherits from +omni_thread. In this case the thread will execute the +run() member function of the new class. One advantage of +this scheme is that thread-specific data can be implemented simply by +having data members of the new class.
+
+When constructed a thread is in the "new" state and has not actually +started. A call to start() causes the thread to begin +executing. A static member function create() is provided to +construct and start a thread in a single call. A thread exits by +calling exit() or by returning from the thread function.
+
+Threads can be either detached or undetached. Detached threads are +threads for which all state will be lost upon exit. Other threads +cannot determine when a detached thread will disappear, and therefore +should not attempt to access the thread object unless some explicit +synchronisation with the detached thread guarantees that it still +exists.
+
+Undetached threads are threads for which storage is not reclaimed +until another thread waits for its termination by calling +join(). An exit value can be passed from an undetached +thread to the thread which joins it.
+
+Detached / undetached threads are distinguished on creation by the +type of function they execute. Undetached threads execute a function +which has a void* return type, whereas detached threads +execute a function which has a void return type. +Unfortunately C++ member functions are not allowed to be distinguished +simply by their return type. Thus in the case of a derived class of +omni_thread which needs an undetached thread, the member +function executed by the thread is called run_undetached() +rather than run(), and it is started by calling +start_undetached() instead of start().
+
+The abstraction currently supports three priorities of thread, but no +guarantee is made of how this will affect underlying thread +scheduling. The three priorities are PRIORITY_LOW, +PRIORITY_NORMAL and PRIORITY_HIGH. By default all +threads run at PRIORITY_NORMAL. A different priority can be +specified on thread creation, or while the thread is running using +set_priority(). A thread's current priority is returned by +priority().
+
+Other functions provided are self() which returns the calling +thread's omni_thread object, yield() which +requests that other threads be allowed to run, id() which +returns an integer id for the thread for use in debugging, +state(), sleep() and get_time().
+
+ + +

4  Per-thread data

+ +omnithread supports per-thread data, via member functions of the +omni_thread object.
+
+First, you must allocate a key for with the +omni_thread::allocate_key() function. Then, any object +whose class is derived from omni_thread::value_t can be +stored using the set_value() function. Values are retrieved +or removed with get_value() and remove_value() +respectively.
+
+When the thread exits, all per-thread data is deleted (hence the base +class with virtual destructor).
+
+Note that the per-thread data functions are not thread safe, +so although you can access one thread's storage from another thread, +there is no concurrency control. Unless you really know what you are +doing, it is best to only access per-thread data from the thread it is +attached to.
+
+ + +

5  Using OMNI threads in your program

+ +Obviously you need to include the omnithread.h header file in +your source code, and link in the omnithread library with your +executable. Because there is a single omnithread.h for all +platforms, certain preprocessor defines must be given as compiler +options. The easiest way to do this is to study the makefiles given +in the examples provided with this distribution. If you are to +include OMNI threads in your own development environment, these are +the necessary preprocessor defines:
+ + + + + + + + + + + + + + + + + + + + + + + + +
PlatformPreprocessor Defines
Sun Solaris 2.x-D__sunos__ -D__sparc__ -D__OSVERSION__=5
 -DSVR4 -DUsePthread -D_REENTRANT
x86 Linux 2.0-D__linux__ -D__i86__ -D__OSVERSION__=2
with linuxthreads 0.5-D_REENTRANT
Digital Unix 3.2-D__osf1__ -D__alpha__ -D__OSVERSION__=3
 -D_REENTRANT
Windows NT-D__NT__ -MD

+ + +

6  Threaded I/O shutdown for Unix

+ +or, how one thread should tell another thread to shut down when it +might be doing a blocking call on a socket.
+
+If you are using omniORB, you don't need to worry about all +this, since omniORB does it for you. This section is only relevant +if you are using omnithread in your own socket-based programming. It +is also seriously out of date.
+
+Unfortunately there doesn't seem to be a standard way of doing this +which works across all Unix systems. I have investigated the +behaviour of Solaris 2.5 and Digital Unix 3.2. On Digital Unix +everything is fine, as the obvious method using shutdown() seems to +work OK. Unfortunately on Solaris shutdown can only be used on a +connected socket, so we need devious means to get around this +limitation. The details are summarised below:
+
+ + +

6.1  read()

+ +Thread A is in a loop, doing read(sock), processing the data, +then going back into the read.
+
+Thread B comes along and wants to shut it down --- it can't cancel +thread A since (i) working out how to clean up according to where A is +in its loop is a nightmare, and (ii) this isn't available in +omnithread anyway.
+
+On Solaris 2.5 and Digital Unix 3.2 the following strategy works:
+
+Thread B does shutdown(sock,2).
+
+At this point thread A is either blocked inside read(sock), or +is elsewhere in the loop. If the former then read will return 0, +indicating that the socket is closed. If the latter then eventually +thread A will call read(sock) and then this will return 0. +Thread A should close(sock), do any other tidying up, and exit.
+
+If there is another point in the loop that thread A can block then +obviously thread B needs to be aware of this and be able to wake it up +in the appropriate way from that point.
+
+ + +

6.2  accept()

+ +Again thread A is in a loop, this time doing an accept on listenSock, +dealing with a new connection and going back into accept. Thread B +wants to cancel it.
+
+On Digital Unix 3.2 the strategy is identical to that for read:
+
+Thread B does shutdown(listenSock,2). Wherever thread A is in +the loop, eventually it will return ECONNABORTED from the +accept call. It should close(listenSock), tidy up as necessary +and exit.
+
+On Solaris 2.5 thread B can't do shutdown(listenSock,2) --- +this returns ENOTCONN. Instead the following strategy can be +used:
+
+First thread B sets some sort of "shutdown flag" associated with +listenSock. Then it does getsockaddr(listenSock) to find out +which port listenSock is on (or knows already), sets up a socket +dummySock, does connect(dummySock, this host, port) and +finally does close(dummySock).
+
+Wherever thread A is in the loop, eventually it will call +accept(listenSock). This will return successfully with a new +socket, say connSock. Thread A then checks to see if the "shutdown +flag" is set. If not, then it's a normal connection. If it is set, +then thread A closes listenSock and connSock, tidies up and exits.
+
+ + +

6.3  write()

+ +Thread A may be blocked in write, or about to go in to a +potentially-blocking write. Thread B wants to shut it down.
+
+On Solaris 2.5:
+
+Thread B does shutdown(sock,2).
+
+If thread A is already in write(sock) then it will return with +ENXIO. If thread A calls write after thread B calls shutdown +this will return EIO.
+
+On Digital Unix 3.2:
+
+Thread B does shutdown(sock,2).
+
+If thread A is already in write(sock) then it will return the +number of bytes written before it became blocked. A subsequent call +to write will then generate SIGPIPE (or EPIPE will be +returned if SIGPIPE is ignored by the thread).
+
+ + +

6.4  connect()

+ +Thread A may be blocked in connect, or about to go in to a +potentially-blocking connect. Thread B wants to shut it down.
+
+On Digital Unix 3.2:
+
+Thread B does shutdown(sock,2).
+
+If thread A is already in connect(sock) then it will return a +successful connection. Subsequent reading or writing will show that +the socket has been shut down (i.e. read returns 0, write generates +SIGPIPE or returns EPIPE). If thread A calls connect +after thread B calls shutdown this will return EINVAL.
+
+On Solaris 2.5:
+
+There is no way to wake up a thread which is blocked in connect. +Instead Solaris forces us through a ridiculous procedure whichever way +we try it. One way is this:
+
+First thread A creates a pipe in addition to the socket. Instead of +shutting down the socket, thread B simply writes a byte to the pipe.
+
+Thread A meanwhile sets the socket to non-blocking mode using +fcntl(sock, F_SETFL, O_NONBLOCK). Then it calls connect +on the socket --- this will return EINPROGRESS. Then it must +call select(), waiting for either sock to become writable or +for the pipe to become readable. If select returns that just sock is +writable then the connection has succeeded. It then needs to set the +socket back to blocking mode using fcntl(sock, F_SETFL, 0). If +instead select returns that the pipe is readable, thread A closes the +socket, tidies up and exits.
+
+An alternative method is similar but to use polling instead of the +pipe. Thread B justs sets a flag and thread A calls select with a +timeout, periodically waking up to see if the flag has been set.
+
+ + +

References

+
[POSIX94]
+Portable Operating System Interface (POSIX) Threads Extension, +P1003.1c Draft 10, +IEEE, +September 1994.
+
+
[Birrell89]
+An Introduction to Programming with Threads, +Research Report 35, +DEC Systems Research Center, +Palo Alto, CA, +January 1989.
+ + + +
+
This document was translated from LATEX by +HEVEA. +
+ + diff --git a/docs/doxygen/other/omnithread.pdf b/docs/doxygen/other/omnithread.pdf new file mode 100644 index 000000000..b54218744 Binary files /dev/null and b/docs/doxygen/other/omnithread.pdf differ diff --git a/docs/doxygen/other/omnithread.ps b/docs/doxygen/other/omnithread.ps new file mode 100644 index 000000000..9e858f0b7 --- /dev/null +++ b/docs/doxygen/other/omnithread.ps @@ -0,0 +1,730 @@ +%!PS-Adobe-2.0 +%%Creator: dvipsk 5.86 p1.5d Copyright 1996-2001 ASCII Corp.(www-ptex@ascii.co.jp) +%%based on dvipsk 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com) +%%Title: omnithread.dvi +%%Pages: 7 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Palatino-Roman Palatino-Italic Palatino-Bold Courier +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips omnithread +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2002.08.15:1756 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3 +def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 +rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 +N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop +false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A +length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse} +forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{ +BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat +{BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch +round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 +rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B +/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M} +B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p +-3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{ +0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "1 July 1998", +% filename = "8r.enc", +% email = "tex-fonts@@tug.org", +% docstring = "Encoding for TrueType or Type 1 fonts +% to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both +% ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin 0 1 255{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}for Metrics/Metrics currentdict end def[2 index currentdict end +definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup +sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll +mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ +exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} +forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def +end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (omnithread.dvi) +@start /Fa 134[ 45 45 66 1[ 51 30 35 35 1[ 45 40 51 71 +25 2[ 25 45 45 25 35 45 37 42 40 8[ 66 3[ 56 51 2[ 56 +71 5[ 30 3[ 56 3[ 66 23[ 30 30 40[{ TeXBase1Encoding ReEncodeFont} 31 +90.9091 /Palatino-Italic rf /Fb 134[ 51 1[ 76 1[ 56 30 +40 35 2[ 51 56 81 30 2[ 30 56 51 35 45 56 40 56 45 14[ 66 +2[ 76 5[ 35 6[ 61 19[ 23 30 23 4[ 25 39[{ TeXBase1Encoding ReEncodeFont} +27 90.9091 /Palatino-Bold rf /Fc 135[ 50 83 1[ 61 33 +44 39 1[ 61 55 61 89 33 2[ 33 61 55 1[ 50 61 44 61 50 +10[ 78 8[ 100 9[ 72 12[ 50 1[ 50 50 50 50 2[ 25 4[ 33 +33 40[{ TeXBase1Encoding ReEncodeFont} 30 99.6264 /Palatino-Bold +rf /Fd 134[ 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +55 55 55 55 55 55 55 55 55 55 55 1[ 55 5[ 55 55 55 55 +55 55 55 55 1[ 55 55 55 55 55 55 1[ 55 55 55 55 55 55 +55 55 55 3[ 55 2[ 55 1[ 55 1[ 55 55 55 55 55 55 55 1[ 55 +55 55 1[ 55 55 55 40[{ TeXBase1Encoding ReEncodeFont} 65 +90.9091 /Courier rf /Fe 141[ 36 12[ 44 56 2[ 45 7[ 61 +61 91 1[ 71 56 48 61 2[ 71 76 3[ 30 31 76 1[ 51 56 70 +64 56 71 10[ 45 3[ 45 45 1[ 55 23 4[ 30 30 40[{ +.167 SlantFont TeXBase1Encoding ReEncodeFont} 29 90.9091 +/Palatino-Roman rf +%DVIPSBitmapFont: Ff cmsy10 10.95 1 +/Ff 1 16 df 15 +D E +%EndDVIPSBitmapFont +/Fg 104[ 91 2[ 45 45 24[ 45 51 47 76 51 55 30 39 36 51 +55 50 53 80 26 51 21 26 53 51 30 44 56 40 50 45 3[ 30 +1[ 30 2[ 61 91 66 71 56 48 61 1[ 55 71 76 86 56 66 30 +31 76 1[ 51 56 70 64 56 71 6[ 23 45 45 45 45 45 45 45 +45 45 45 55 23 30 23 55 1[ 30 30 25 4[ 34 30[ 55 55 2[{ +TeXBase1Encoding ReEncodeFont} 75 90.9091 /Palatino-Roman +rf /Fh 134[ 66 60 100 1[ 73 40 53 47 1[ 73 66 73 106 +2[ 40 40 73 66 47 60 73 53 73 60 11[ 93 80 73 86 1[ 73 +100 100 120 3[ 47 18[ 60 60 60 60 60 60 1[ 35 1[ 40 45[{ +TeXBase1Encoding ReEncodeFont} 38 119.552 /Palatino-Bold +rf /Fi 137[ 50 2[ 39 9[ 28 3[ 39 50 17[ 66 82[{ +TeXBase1Encoding ReEncodeFont} 6 99.6264 /Palatino-Italic +rf /Fj 137[ 56 1[ 32 42 39 2[ 54 58 88 3[ 29 58 55 1[ 48 +61 44 55 50 12[ 61 1[ 67 3[ 83 1[ 61 8[ 71 1[ 78 14[ 50 +50 50 9[ 78 38[{ TeXBase1Encoding ReEncodeFont} 25 99.6264 +/Palatino-Roman rf /Fk 139[ 47 61 57 2[ 78 83 4[ 42 83 +2[ 69 88 64 79 72 12[ 88 4[ 113 119 136 3[ 48 7[ 112 +65[{ TeXBase1Encoding ReEncodeFont} 18 143.462 /Palatino-Roman +rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop Fk 728 918 a(The) 36 b(OMNI) g(Thr) m(ead) f(Abstracti) n(on) p +Fj 1293 1176 a(T) -9 b(ristan) 26 b(Richar) n(dson) 1022 +1293 y(A) -7 b(T&T) 24 b(Laboratories) i(Cambridge) p +Fi 1192 1504 a(Revised) p Fj 24 w(November) f(2001) p +Fh 63 1961 a(1) 119 b(Introduction) p Fg 63 2183 a(The) 20 +b(OMNI) h(thr) n(ead) g(abstraction) g(is) h(des) n(igned) f(to) f(pr) n +(ovide) h(a) h(common) f(set) f(of) h(thr) n(ead) g(oper) n(-) 63 +2296 y(ations) h(for) g(use) g(in) h(pr) n(ograms) f(written) f(in) i +(C++.) 29 b(Pr) n(ograms) 22 b(written) g(using) f(the) h(abstraction) +63 2409 y(should) 30 b(be) g(much) i(easier) e(to) g(port) g(betwee) n +(n) h(dif) n(fer) n(ent) g(ar) n(chi) r(tectur) l(es) g(with) g(dif) n +(fer) n(ent) f(un-) 63 2522 y(derlying) 21 b(thr) n(eads) h +(primitives.) 204 2640 y(The) 17 b(pr) n(ogramming) h(interface) g(is) f +(designed) f(to) h(be) h(similar) h(to) e(the) g(C) i(language) e +(interface) 63 2753 y(to) k(POSIX) h(thr) n(eads) f(\(IEEE) g(draft) h +(standar) n(d) f(100) r(3.1c) i(\227) f(pr) n(eviously) g(1003) r(.4a,) +g(often) g(known) 63 2866 y(as) g(\223pthr) n(eads\224) h([POSIX94]\).) +204 2985 y(Much) 18 b(of) f(the) g(abstraction) i(consists) d(of) i +(simple) g(C++) g(object) g(wrappers) e(ar) n(ound) h(pthr) n(ead) 63 +3098 y(calls.) 28 b(Howe) n(ver) 20 b(for) f(some) f(featur) n(es) g +(such) h(as) h(thr) n(ead-spe) n(ci\002c) h(data,) f(a) f(better) f +(interface) i(can) 63 3211 y(be) i(of) n(fer) n(ed) g(because) h(of) f +(the) g(use) g(of) g(C++.) 204 3329 y(Some) 28 b(of) h(the) f(mor) n(e) +h(complex) f(featur) n(es) g(of) h(pthr) n(eads) f(ar) n(e) h(not) f +(suppo) n(rted) g(because) h(of) 63 3442 y(the) e(dif) n(\002culty) i +(of) f(ensuring) g(the) f(same) h(featur) n(es) g(can) h(be) f(of) n +(fer) n(ed) g(on) g(top) g(of) g(other) f(thr) n(ead) 63 +3555 y(sys) n(tems.) f(Such) 17 b(featur) n(es) g(include) h(thr) n +(ead) f(cancell) r(ation) g(and) h(complex) g(schedu) n(ling) h(contr) n +(ol) 63 3668 y(\(thoug) n(h) k(simple) g(thr) n(ead) f(priorities) g +(ar) n(e) h(supp) n(orted\).) 204 3787 y(The) i(abstraction) h(layer) h +(is) f(curr) n(ently) f(implemented) g(for) h(the) f(following) i(ar) n +(chitectur) n(es) 63 3900 y(/) 22 b(thr) n(ead) h(sys) n(tems:) p +Ff 199 4141 a(\017) p Fg 46 w(Solaris) g(2.x) g(using) f(pthr) n(eads) f +(draft) h(10) p Ff 199 4351 a(\017) p Fg 46 w(Solaris) h(2.x) g(using) f +(solaris) g(thr) n(eads) g(\(but) h(pthr) n(eads) e(version) h(is) h +(now) f(standar) n(d\)) p Ff 199 4561 a(\017) p Fg 46 +w(Alpha) h(OSF1) g(using) f(pthr) n(eads) f(draft) i(4) p +Ff 199 4772 a(\017) p Fg 46 w(W) -5 b(indows) 21 b(NT) h(using) g(NT) g +(thr) n(eads) p Ff 199 4982 a(\017) p Fg 46 w(Linux) g(2.x) h(using) f +(Linuxthr) n(ead) g(0.5) h(\(which) h(is) e(based) g(on) h(pthr) n +(eads) e(draft) i(10\)) p Ff 199 5193 a(\017) p Fg 46 +w(Linux) f(2.x) h(using) f(MIT) g(pthr) n(eads) f(\(which) j(is) f +(based) f(on) g(draft) h(8\)) p Ff 199 5403 a(\017) p +Fg 46 w(A) -7 b(TMos) 22 b(using) g(pthr) n(eads) f(draft) h(6) i +(\(but) e(not) g(V) -5 b(irata) 23 b(A) -7 b(TMos\)) 1684 +5652 y(1) p 90 rotate dyy eop +%%Page: 2 2 +2 1 bop Fg 221 249 a(2) p Fe 1797 w(2) 91 b(SYNCHRONI) n(SA) -7 +b(TION) 22 b(OBJECTS) p Fg 362 548 a(See) h(the) p Fd +22 w(omni) n(thre) n(ad.h) p Fg 22 w(header) f(\002le) i(for) f(full) i +(det) n(ail) r(s) e(of) g(the) g(API.) f(The) h(des) n(criptions) 221 +661 y(below) 35 b(assume) g(you) g(have) h(some) e(pr) n(evious) h +(knowled) n(ge) g(of) h(thr) n(eads) n(,) j(mutexes) n(,) g(condi-) 221 +774 y(tion) f(varia) r(bles) g(and) g(semaphor) n(es) n(.) 75 +b(Also) 38 b(r) n(efer) f(to) h(other) f(document) n(ation) i(\([Birr) n +(ell89) r(],) 221 887 y([POSIX94) q(]\)) 22 b(for) g(further) f +(explanation) i(of) f(thes) n(e) g(ideas) g(\(particularly) h +(condition) f(variab) r(les,) 221 1000 y(the) g(use) g(of) g(which) h +(may) g(not) f(be) h(particularly) h(intuitive) f(when) f(\002rst) f +(encounter) n(ed) n(\).) p Fh 221 1299 a(2) 119 b(Synchronisation) 31 +b(objects) p Fg 221 1510 a(Synchr) n(onisation) 26 b(objects) h(ar) n +(e) g(used) e(to) h(synchr) n(onise) g(thr) n(eads) g(within) h(the) f +(same) h(pr) n(ocess) n(.) 221 1623 y(Ther) n(e) j(is) i(no) f(inter) n +(-pr) n(ocess) f(synchr) n(onisation) g(pr) n(ovided.) 53 +b(The) 30 b(synchr) n(onisation) h(objects) 221 1735 +y(pr) n(ovided) 22 b(ar) n(e) h(mutexes) n(,) g(condition) f(variab) r +(les) g(and) h(counting) f(semaphor) n(e) n(s.) p Fc +221 1991 a(2.1) 99 b(Mutex) p Fg 221 2168 a(An) 26 b(object) g(of) h +(typ) n(e) p Fd 26 w(omni) n(_mute) n(x) p Fg 26 w(is) g(use) n(d) f +(for) h(mutual) f(exclusion.) 39 b(It) 26 b(pr) n(ovides) f(two) g(op-) +221 2281 y(erations,) p Fd 37 w(lock\() n(\)) p Fg 35 +w(and) p Fd 35 w(unloc) n(k\(\)) p Fg(.) 64 b(The) 35 +b(alternative) h(names) p Fd 35 w(acq) n(uire\() n(\)) p +Fg 35 w(and) p Fd 35 w(re-) 221 2393 y(leas) n(e\(\)) p +Fg 19 w(can) 21 b(be) f(used) f(if) i(pr) n(eferr) n(ed) n(.) 27 +b(Behaviour) 20 b(is) g(unde\002ne) n(d) g(when) f(a) i(thr) n(ead) f +(attempt) n(s) 221 2506 y(to) 30 b(lock) h(the) e(same) i(mutex) f +(again) h(or) f(when) g(a) h(mutex) f(is) h(locked) e(by) i(one) e(thr) +n(ead) h(and) h(un-) 221 2619 y(locked) 22 b(by) h(a) g(dif) n(fer) n +(ent) f(thr) n(ead.) p Fc 221 2874 a(2.2) 99 b(Condition) 26 +b(V) -11 b(ariable) p Fg 221 3051 a(A) 28 b(condition) f(varia) r(ble) h +(is) g(r) n(epr) n(ese) n(nted) f(by) h(an) p Fd 28 w(omn) n(i_con) n +(diti) n(on) p Fg 27 w(and) g(is) g(used) e(for) i(sig-) 221 +3164 y(nalli) r(ng) 20 b(betwee) n(n) g(thr) n(eads.) 26 +b(A) 21 b(call) h(to) p Fd 19 w(wait\() n(\)) p Fg 20 +w(causes) e(a) h(thr) n(ead) e(to) h(wait) h(on) f(the) f(condition) 221 +3277 y(varia) r(ble.) 45 b(A) 28 b(call) i(to) p Fd 27 +w(sign) n(al\(\)) p Fg 27 w(wakes) d(up) h(at) g(least) g(one) f(thr) n +(ead) h(if) h(any) f(ar) n(e) g(waiting.) 45 b(A) 221 +3390 y(call) 25 b(to) p Fd 22 w(bro) n(adca) n(st\(\)) p +Fg 21 w(wakes) d(up) g(all) i(thr) n(eads) e(waiting) h(on) f(the) g +(condition) g(varia) r(ble.) 362 3503 y(When) 30 b(constr) o(ucte) n +(d,) i(a) e(pointer) f(to) h(an) p Fd 30 w(omni) n(_mute) n(x) p +Fg 30 w(must) f(be) h(given.) 50 b(A) 30 b(condition) 221 +3616 y(varia) r(ble) p Fd 33 w(wait\() n(\)) p Fg 33 +w(has) j(an) h(implic) r(it) f(mutex) p Fd 33 w(unlo) n(ck\(\)) p +Fg 32 w(and) p Fd 33 w(lock) n(\(\)) p Fg 33 w(ar) n(ound) g(it.) 60 +b(The) 221 3729 y(link) 30 b(between) f(condition) g(varia) r(ble) h +(and) g(mutex) f(lasts) g(for) h(the) f(lifetime) i(of) e(the) g +(condition) 221 3842 y(varia) r(ble) c(\(unlike) h(pthr) n(eads) e +(wher) n(e) g(the) h(link) h(is) f(only) g(for) g(the) g(duration) f +(of) i(the) e(wait\).) 37 b(The) 221 3955 y(same) 23 +b(mutex) f(may) h(be) f(used) f(with) i(several) f(condition) h(variab) +r(les.) 362 4068 y(A) c(wait) g(with) g(a) g(timeout) f(can) i(be) e +(achieved) h(by) g(call) r(ing) p Fd 19 w(tim) n(ed_w) n(ait\(\)) p +Fg -2 w(.) 27 b(This) 18 b(is) h(given) 221 4181 y(an) 27 +b(absolute) e(time) h(to) f(wait) h(until.) 38 b(The) 26 +b(r) n(outine) p Fd 25 w(omn) n(i_thr) n(ead:) n(:get_) n(time) n(\(\)) +p Fg 25 w(can) h(be) 221 4293 y(used) 21 b(to) h(turn) g(a) h(r) n +(elativ) r(e) f(time) g(into) h(an) g(absolute) f(time.) p +Fd 28 w(tim) n(ed_wa) n(it\(\)) p Fg 21 w(r) n(eturns) p +Fd 21 w(true) p Fg 21 w(if) 221 4406 y(the) 27 b(condition) h(was) g +(signalled,) p Fd 29 w(false) p Fg 26 w(if) h(the) f(time) g(expir) n +(ed) f(befor) n(e) g(the) h(condition) f(vari) r(-) 221 +4519 y(able) d(was) e(signalled.) p Fc 221 4774 a(2.3) 99 +b(Counting) 26 b(semaphores) p Fg 221 4951 a(An) p Fd +21 w(omn) n(i_sem) n(apho) n(re) p Fg 20 w(is) 21 b(a) h(counting) e +(semaphor) n(e) n(.) 28 b(When) 20 b(cr) n(eated) g(it) h(is) g(given) g +(an) g(initial) 221 5064 y(unsigned) j(intege) n(r) i(value.) 36 +b(When) p Fd 25 w(wai) n(t\(\)) p Fg 24 w(is) 26 b(called,) g(the) f +(value) h(is) f(decr) n(emente) n(d) g(if) h(non-) 221 +5177 y(zer) n(o.) 43 b(If) 27 b(the) g(value) h(is) f(zer) n(o) h(then) +f(the) f(thr) n(ead) h(blocks) h(instead.) 41 b(When) p +Fd 27 w(post) n(\(\)) p Fg 27 w(is) 27 b(cal) r(led,) 221 +5290 y(if) h(any) g(thr) n(eads) e(ar) n(e) i(blocked) f(in) p +Fd 27 w(wait\() n(\)) p Fg(,) h(exactly) f(one) g(thr) n(ead) g(is) g +(woken.) 41 b(If) 27 b(no) g(thr) n(eads) 221 5403 y(wer) n(e) 22 +b(blocked) g(then) g(the) g(value) h(of) g(the) e(semaphor) n(e) h(is) h +(incr) n(emented.) p 90 rotate dyy eop +%%Page: 3 3 +3 2 bop Fg 3306 249 a(3) 204 548 y(If) 27 b(a) h(thr) n(ead) e(cal) r +(ls) p Fd 27 w(try) n(_wait) n(\(\)) p Fg(,) h(then) g(the) f(thr) n +(ead) g(won't) h(block) h(if) f(the) g(semaphor) n(e's) 63 +661 y(value) c(is) g(0,) g(r) n(eturning) p Fd 21 w(false) p +Fg 21 w(instead.) 204 777 y(Ther) n(e) f(is) g(no) h(way) f(of) h +(query) n(ing) g(the) f(value) h(of) g(the) f(semaphor) n(e) n(.) p +Fh 63 1095 a(3) 119 b(Thread) 29 b(object) p Fg 63 1313 +a(A) 23 b(thr) n(ead) g(is) h(r) n(epr) n(ese) n(nted) e(by) i(an) p +Fd 24 w(omni) n(_thr) n(ead) p Fg 23 w(object.) 30 b(Ther) n(e) 23 +b(ar) n(e) h(br) n(oadly) g(two) e(dif) n(fer) n(-) 63 +1426 y(ent) f(ways) i(in) g(which) g(it) g(can) g(be) g(used) n(.) 204 +1542 y(The) 28 b(\002rst) g(way) h(is) h(simply) f(to) f(cr) n(eate) h +(an) p Fd 30 w(omn) n(i_thr) n(ead) p Fg 28 w(object,) h(giving) g(a) f +(particula) r(r) 63 1655 y(function) c(which) h(the) e(thr) n(ead) h +(should) f(execute) n(.) 36 b(This) 25 b(is) g(like) g(the) g(POSIX) f +(\(or) i(any) f(other) n(\)) h(C) 63 1768 y(language) c(interface.) 204 +1884 y(The) k(second) f(method) h(of) h(use) e(is) i(to) f(cr) n(eate) h +(a) g(new) g(class) g(which) g(inherits) f(fr) n(om) p +Fd 28 w(omn) n(i_) 63 1997 y(thr) n(ead) p Fg(.) 50 b(In) 31 +b(this) f(case) g(the) g(thr) n(ead) g(will) i(execute) d(the) p +Fd 29 w(run\(\)) p Fg 29 w(member) h(function) h(of) f(the) 63 +2109 y(new) 22 b(class.) 29 b(One) 23 b(advantage) g(of) g(this) g +(scheme) f(is) h(that) g(thr) n(ead-speci\002c) g(data) g(can) h(be) f +(imple-) 63 2222 y(mented) e(simply) h(by) h(having) g(data) g(members) +f(of) h(the) f(new) g(class.) 204 2339 y(When) f(constr) o(ucted) g(a) i +(thr) n(ead) f(is) g(in) h(the) e("new") h(state) f(and) h(has) g(not) g +(actuall) r(y) g(starte) n(d.) 28 b(A) 63 2451 y(call) j(to) p +Fd 29 w(sta) n(rt\(\)) p Fg 28 w(causes) e(the) g(thr) n(ead) g(to) g +(begin) g(executing.) 47 b(A) 29 b(static) h(member) f(function) p +Fd 63 2564 a(cre) n(ate\() n(\)) p Fg 32 w(is) j(pr) n(ovided) f(to) g +(constr) o(uct) g(and) g(start) g(a) i(thr) n(ead) e(in) h(a) g(single) +g(call.) 57 b(A) 31 b(thr) n(ead) 63 2677 y(exits) 21 +b(by) i(call) r(ing) p Fd 22 w(exit\() n(\)) p Fg 22 +w(or) g(by) f(r) n(eturning) g(fr) n(om) h(the) f(thr) n(ead) g +(function.) 204 2793 y(Thr) n(eads) 27 b(can) j(be) e(either) g +(detached) f(or) h(undetached) n(.) 46 b(Detached) 28 +b(thr) n(eads) g(ar) n(e) h(thr) n(eads) 63 2906 y(for) h(which) i(all) +g(state) e(will) i(be) f(lost) f(upon) g(exit.) 52 b(Other) 30 +b(thr) n(eads) g(cannot) h(dete) n(rmine) g(when) 63 +3019 y(a) e(detached) f(thr) n(ead) h(will) h(disappear) -7 +b(,) 31 b(and) e(ther) n(efor) n(e) f(should) g(not) h(attempt) f(to) g +(access) h(the) 63 3132 y(thr) n(ead) 23 b(object) g(unless) f(some) h +(explicit) h(synchr) n(onisation) f(with) g(the) g(detached) f(thr) n +(ead) h(guar) n(-) 63 3245 y(antees) e(that) h(it) h(still) g(exists.) +204 3361 y(Undet) n(ached) 33 b(thr) n(eads) f(ar) n(e) i(thr) n(eads) e +(for) h(which) g(storage) f(is) h(not) f(r) n(eclai) r(med) g(until) i +(an-) 63 3474 y(othe) n(r) g(thr) n(ead) g(waits) g(for) g(its) g +(termination) g(by) g(call) r(ing) p Fd 34 w(joi) n(n\(\)) p +Fg(.) 61 b(An) 34 b(exit) g(value) h(can) g(be) 63 3587 +y(passe) n(d) 23 b(fr) n(om) g(an) g(undet) n(ached) g(thr) n(ead) f +(to) g(the) g(thr) n(ead) g(which) h(joins) g(it.) 204 +3703 y(Detached) 31 b(/) h(undetached) e(thr) n(eads) h(ar) n(e) i +(distinguish) n(ed) f(on) f(cr) n(eation) h(by) g(the) f(type) g(of) 63 +3816 y(function) 24 b(they) e(execute.) 30 b(Undetached) 22 +b(thr) n(eads) h(execute) g(a) h(function) g(which) g(has) g(a) p +Fd 25 w(voi) n(d*) p Fg 63 3929 a(r) n(eturn) c(typ) n(e,) h(wher) n +(eas) f(detached) f(thr) n(eads) h(execute) f(a) j(function) f(which) g +(has) g(a) p Fd 21 w(void) p Fg 19 w(r) n(eturn) 63 4042 +y(typ) n(e.) 52 b(Unfortunate) n(ly) 31 b(C++) g(member) g(functions) f +(ar) n(e) h(not) f(allowed) g(to) g(be) h(distingu) n(ished) 63 +4155 y(simply) 26 b(by) h(their) f(r) n(eturn) g(type) n(.) 40 +b(Thus) 26 b(in) h(the) f(case) h(of) g(a) g(derived) f(class) h(of) p +Fd 26 w(omni_) n(thre) n(ad) p Fg 63 4268 a(which) 20 +b(needs) e(an) j(undet) n(ached) f(thr) n(ead,) g(the) f(member) h +(function) g(execute) n(d) g(by) g(the) f(thr) n(ead) g(is) 63 +4380 y(called) p Fd 19 w(run_u) n(ndet) n(ache) n(d\(\)) p +Fg 18 w(rather) f(than) p Fd 19 w(run\() n(\)) p Fg(,) h(and) g(it) g +(is) g(started) e(by) i(calli) r(ng) p Fd 18 w(star) n(t_) 63 +4493 y(und) n(etac) n(hed\(\)) p Fg 21 w(instead) j(of) p +Fd 22 w(start) n(\(\)) p Fg(.) 204 4610 y(The) i(abstraction) i(curr) n +(ently) e(suppo) n(rts) h(thr) n(ee) f(priorities) g(of) h(thr) n(ead,) +g(but) g(no) g(guarantee) 63 4722 y(is) 33 b(made) g(of) h(how) f(this) +g(will) h(af) n(f) r(ect) f(underlying) f(thr) n(ead) h(scheduling.) 59 +b(The) 33 b(thr) n(ee) f(priori-) 63 4835 y(ties) 18 +b(ar) n(e) p Fd 20 w(PRIO) n(RITY) n(_LOW) p Fg(,) p +Fd 18 w(PRIO) n(RITY) n(_NOR) n(MAL) p Fg 19 w(and) p +Fd 19 w(PRIO) n(RITY) n(_HIG) n(H) p Fg(.) h(By) g(default) g(all) 63 +4948 y(thr) n(eads) i(r) o(un) i(at) p Fd 23 w(PRIO) n(RITY) n(_NORM) n +(AL) p Fg(.) f(A) g(dif) n(fer) n(ent) h(priority) f(can) i(be) e +(speci\002ed) g(on) g(thr) n(ead) 63 5061 y(cr) n(eation,) h(or) f +(while) h(the) f(thr) n(ead) g(is) h(r) o(unning) g(using) p +Fd 22 w(set_) n(prio) n(rity\() n(\).) p Fg 28 w(A) g(thr) n(ead's) f +(cur) n(-) 63 5174 y(r) n(ent) g(priority) g(is) g(r) n(eturned) f(by) p +Fd 23 w(pri) n(ority) n(\(\)) p Fg(.) 204 5290 y(Other) d(functions) g +(pr) n(ovided) g(ar) n(e) p Fd 19 w(sel) n(f\(\)) p Fg +18 w(which) h(r) n(eturns) e(the) h(calli) r(ng) g(thr) n(ead's) p +Fd 18 w(omn) n(i_) 63 5403 y(thr) n(ead) p Fg 36 w(object,) p +Fd 40 w(yie) n(ld\(\)) p Fg 35 w(which) 38 b(r) n(eques) n(ts) e(that) h +(other) e(thr) n(eads) h(be) h(allowed) g(to) f(r) o(un,) p +90 rotate dyy eop +%%Page: 4 4 +4 3 bop Fg 221 249 a(4) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23 +b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fd 221 548 a(id\(\)) p +Fg 27 w(which) 29 b(r) n(eturns) e(an) i(intege) n(r) g(id) f(for) h +(the) e(thr) n(ead) h(for) g(use) g(in) h(debug) n(ging,) p +Fd 29 w(state) n(\(\)) p Fg(,) p Fd 221 661 a(slee) n(p\(\)) p +Fg 22 w(and) p Fd 22 w(get_t) n(ime\() n(\)) p Fg(.) p +Fh 221 953 a(4) 119 b(Per) n(-threa) n(d) 30 b(data) p +Fg 221 1164 a(omnithr) n(ead) 22 b(suppo) n(rts) g(per) n(-thr) n(ead) f +(data,) h(via) i(member) e(functions) f(of) i(the) p +Fd 21 w(omni) n(_thr) n(ead) p Fg 221 1277 a(object.) 362 +1390 y(First,) d(you) g(must) h(allocate) h(a) f(key) f(for) g(with) h +(the) p Fd 20 w(omni) n(_thre) n(ad::) n(allo) n(cate_) n(key\() n(\)) p +Fg 221 1502 a(function.) 28 b(Then,) 21 b(any) h(object) g(whose) f +(class) h(is) g(derived) f(fr) n(om) p Fd 23 w(omni) n(_thr) n(ead::) n +(valu) n(e_t) p Fg 221 1615 a(can) 27 b(be) f(stor) n(e) n(d) g(using) f +(the) p Fd 26 w(set) n(_val) n(ue\(\)) p Fg 25 w(function.) 38 +b(V) -8 b(alues) 25 b(ar) n(e) h(r) n(etrieved) f(or) h(r) n(emoved) 221 +1728 y(with) p Fd 23 w(get) n(_valu) n(e\(\)) p Fg 21 +w(and) p Fd 23 w(remo) n(ve_v) n(alue\() n(\)) p Fg 22 +w(r) n(espectively) -10 b(.) 362 1841 y(When) 23 b(the) g(thr) n(ead) g +(exits,) g(all) i(per) n(-thr) n(ead) e(data) h(is) g(delet) n(ed) f +(\(hence) h(the) e(base) i(class) g(with) 221 1954 y(virtual) g(dest) n +(r) o(uctor\).) 362 2067 y(Note) 17 b(that) i(the) f(per) n(-thr) n +(ead) f(data) i(functions) f(ar) n(e) p Fb 19 w(not) p +Fg 18 w(thr) n(ead) g(safe,) i(so) d(although) i(you) e(can) 221 +2180 y(access) 29 b(one) e(thr) n(ead's) h(storage) f(fr) n(om) i +(another) f(thr) n(ead,) h(ther) n(e) e(is) i(no) f(concurr) n(ency) g +(contr) n(ol.) 221 2293 y(Unless) j(you) g(r) n(eall) r(y) h(know) f +(what) h(you) f(ar) n(e) i(doing,) g(it) g(is) f(best) f(to) h(only) g +(access) g(per) n(-thr) n(ead) 221 2406 y(data) 23 b(fr) n(om) g(the) f +(thr) n(ead) g(it) h(is) g(attached) f(to.) p Fh 221 +2698 a(5) 119 b(Using) 31 b(OMNI) d(threads) h(in) h(your) g(program) p +Fg 221 2909 a(Obvi) r(ously) 16 b(you) h(need) g(to) g(include) h(the) p +Fd 16 w(omnit) n(hrea) n(d.h) p Fg 17 w(header) e(\002le) i(in) g(your) +f(sour) n(ce) g(code,) 221 3021 y(and) 25 b(link) g(in) h(the) e +(omnithr) n(ead) g(libra) r(ry) g(with) h(your) f(execut) n(abl) r(e.) +34 b(Because) 23 b(ther) n(e) h(is) h(a) g(single) p +Fd 221 3134 a(omni) n(threa) n(d.h) p Fg 30 w(for) 32 +b(all) h(platforms,) h(certain) e(pr) n(epr) n(oces) n(sor) f +(de\002nes) f(must) h(be) g(given) h(as) 221 3247 y(compiler) 25 +b(options) n(.) 33 b(The) 23 b(easiest) g(way) h(to) g(do) f(this) h +(is) g(to) g(stud) n(y) g(the) g(make\002les) f(given) h(in) h(the) 221 +3360 y(examples) i(pr) n(ovided) g(with) g(this) g(distribution.) 42 +b(If) 27 b(you) g(ar) n(e) g(to) g(include) h(OMNI) f(thr) n(eads) g +(in) 221 3473 y(your) 18 b(own) g(development) g(envir) n(onment,) h +(thes) n(e) g(ar) n(e) g(the) f(necessary) g(pr) n(epr) n(oce) n(ssor) g +(de\002nes) n(:) p 362 3567 3287 4 v 360 3680 4 113 v +412 3646 a(Platform) p 1312 3680 V 599 w(Pr) n(epr) n(ocess) n(or) 23 +b(De\002nes) p 3648 3680 V 362 3683 3287 4 v 362 3700 +V 360 3813 4 113 v 412 3779 a(Sun) f(Solaris) h(2.x) p +1312 3813 V Fd 365 w(-D__) n(suno) n(s__) 54 b(-D_) n(_spa) n(rc__) f +(-D__) n(OSVER) n(SION) n(__=5) p 3648 3813 V 360 3926 +V 1312 3926 V 1363 3892 a(-DSV) n(R4) h(-DUs) n(ePth) n(read) f(-D_R) n +(EENT) n(RANT) p 3648 3926 V 362 3929 3287 4 v 360 4042 +4 113 v Fg 412 4008 a(x86) 24 b(Linux) e(2.0) p 1312 +4042 V Fd 418 w(-D__) n(linu) n(x__) 54 b(-D_) n(_i86) n(__) g(-D__) n +(OSVE) n(RSION) n(__=2) p 3648 4042 V 360 4155 V Fg 412 +4121 a(with) 23 b(linuxthr) n(eads) f(0.5) p 1312 4155 +V Fd 100 w(-D_R) n(EENT) n(RANT) p 3648 4155 V 362 4158 +3287 4 v 360 4271 4 113 v Fg 412 4237 a(Digital) i(Unix) f(3.2) p +1312 4271 V Fd 320 w(-D__) n(osf1) n(__) 54 b(-D__) n(alph) n(a__) g +(-D_) n(_OSV) n(ERSIO) n(N__=) n(3) p 3648 4271 V 360 +4384 V 1312 4384 V 1363 4350 a(-D_R) n(EENT) n(RANT) p +3648 4384 V 362 4387 3287 4 v 360 4500 4 113 v Fg 412 +4466 a(W) -5 b(indows) 22 b(NT) p 1312 4500 V Fd 411 +w(-D__) n(NT__) 53 b(-MD) p 3648 4500 V 362 4503 3287 +4 v Fh 221 4740 a(6) 119 b(Threaded) 29 b(I/O) g(shutdown) h(for) g +(Unix) p Fg 221 4951 a(or) -7 b(,) 20 b(how) e(one) g(thr) n(ead) h +(shou) n(ld) h(tell) f(another) f(thr) n(ead) g(to) h(shut) f(down) g +(when) g(it) h(might) g(be) g(doing) 221 5064 y(a) k(blocking) g(cal) r +(l) g(on) f(a) h(socket) n(.) p Fb 362 5177 a(If) h(you) e(are) i +(using) e(omniOR) n(B,) h(you) e(don') n(t) i(need) g(to) g(worry) f +(about) g(all) i(this,) f(since) h(om-) 221 5290 y(niORB) i(does) h(it) +h(for) f(you) n(.) p Fg 41 w(This) g(section) f(is) h(only) g(r) n +(elevant) g(if) h(you) e(ar) n(e) h(using) f(omnithr) n(ead) 221 +5403 y(in) d(your) f(own) g(socket) n(-based) h(pr) n(ogramming.) k(It) +22 b(is) h(also) g(serious) n(ly) g(out) f(of) h(date.) p +90 rotate dyy eop +%%Page: 5 5 +5 4 bop Fe 63 249 a(6.1) 91 b(r) n(ead\(\)) p Fg 2800 +w(5) 204 548 y(Unfortunate) n(ly) 35 b(ther) n(e) e(doe) n(sn't) h +(seem) f(to) h(be) g(a) h(standar) n(d) e(way) i(of) f(doing) f(this) h +(which) 63 661 y(works) 19 b(acr) n(oss) i(all) i(Unix) e(syst) n(ems.) +27 b(I) 21 b(have) g(investigated) f(the) h(behaviour) g(of) g(Solaris) +h(2.5) g(and) 63 774 y(Digital) k(Unix) g(3.2.) 36 b(On) 26 +b(Digital) h(Unix) e(everyth) n(ing) h(is) f(\002ne,) g(as) h(the) e +(obvious) h(method) f(using) 63 887 y(shutd) n(own\(\)) 32 +b(seems) f(to) h(work) f(OK.) h(Unfortunately) f(on) h(Solaris) h(shut) +n(down) f(can) h(only) f(be) 63 1000 y(used) 25 b(on) h(a) h(connected) +e(socke) n(t,) i(so) f(we) g(need) f(devious) h(means) g(to) g(get) f +(ar) n(ound) h(this) g(lim) r(ita-) 63 1112 y(tion.) h(The) 22 +b(details) g(ar) n(e) h(summarised) g(below:) p Fc 63 +1429 a(6.1) 99 b(read\(\)) p Fg 63 1627 a(Thr) n(ead) 28 +b(A) h(is) g(in) h(a) g(loop,) g(doing) p Fd 28 w(rea) n(d\(soc) n(k\)) +p Fg(,) g(pr) n(ocess) n(ing) f(the) g(data,) h(then) f(going) f(back) +63 1739 y(into) 22 b(the) g(r) n(ead.) 204 1862 y(Thr) n(ead) 30 +b(B) h(comes) f(along) h(and) g(wants) f(to) g(shut) g(it) h(down) f +(\227) h(it) g(can't) g(cancel) h(thr) n(ead) f(A) 63 +1975 y(since) 21 b(\(i\)) h(working) e(out) g(how) g(to) h(clean) h(up) +e(accor) n(ding) i(to) e(wher) n(e) g(A) h(is) g(in) h(its) f(loop) f +(is) h(a) h(night-) 63 2088 y(mar) n(e,) h(and) f(\(ii\)) i(this) f +(isn't) f(ava) r(ilabl) r(e) g(in) h(omnithr) n(ead) f(anyway) -10 +b(.) 204 2211 y(On) 23 b(Solaris) g(2.5) g(and) g(Digital) h(Unix) f +(3.2) g(the) f(following) h(strate) n(gy) f(works:) 204 +2334 y(Thr) n(ead) g(B) g(does) p Fd 21 w(shut) n(down\() n(sock) n +(,2\)) p Fg(.) 204 2457 y(At) g(this) g(point) h(thr) n(ead) f(A) g(is) +h(either) f(blocked) g(inside) p Fd 23 w(rea) n(d\(so) n(ck\)) p +Fg(,) g(or) g(is) h(elsewhe) n(r) n(e) g(in) 63 2570 +y(the) 18 b(loop.) 26 b(If) 18 b(the) g(former) h(then) f(r) n(ead) h +(will) h(r) n(eturn) e(0,) i(indicating) f(that) g(the) f(socke) n(t) h +(is) g(closed.) 26 b(If) 63 2683 y(the) 21 b(latter) h(then) f +(eventually) h(thr) n(ead) g(A) g(will) i(call) p Fd +24 w(rea) n(d\(so) n(ck\)) p Fg 21 w(and) f(then) e(this) h(will) h(r) n +(eturn) 63 2796 y(0.) 28 b(Thr) n(ead) 22 b(A) h(should) p +Fd 21 w(clos) n(e\(soc) n(k\)) p Fg(,) f(do) g(any) g(other) g(tidying) +f(up,) h(and) h(exit.) 204 2919 y(If) 34 b(ther) n(e) g(is) h(another) f +(point) g(in) h(the) e(loop) i(that) f(thr) n(ead) g(A) h(can) g(block) +g(then) f(obviously) 63 3032 y(thr) n(ead) 19 b(B) h(needs) f(to) h(be) +g(awar) n(e) h(of) f(this) g(and) g(be) h(able) g(to) e(wake) h(it) h +(up) f(in) g(the) g(appr) n(opriate) g(way) 63 3145 y(fr) n(om) j(that) +f(point.) p Fc 63 3462 a(6.2) 99 b(accept\(\)) p Fg 63 +3659 a(Again) 25 b(thr) n(ead) g(A) h(is) f(in) h(a) g(loop,) g(this) f +(time) h(doing) e(an) i(acc) r(ept) e(on) h(listenSock,) g(dealing) h +(with) 63 3772 y(a) d(new) f(connection) g(and) h(going) e(back) j +(into) e(accept.) 28 b(Thr) n(ead) 22 b(B) g(wants) h(to) f(cancel) h +(it.) 204 3895 y(On) g(Digital) h(Unix) f(3.2) g(the) f(strateg) n(y) g +(is) h(identical) h(to) e(that) g(for) h(r) n(ead:) 204 +4018 y(Thr) n(ead) 39 b(B) g(does) p Fd 38 w(shut) n(down) n(\(list) n +(enSo) n(ck,2) n(\)) p Fg(.) 79 b(Wher) n(ever) 38 b(thr) n(ead) h(A) h +(is) f(in) h(the) 63 4131 y(loop,) i(eventually) c(it) h(will) h(r) n +(eturn) p Fd 38 w(ECONN) n(ABOR) n(TED) p Fg 38 w(fr) n(om) f(the) f +(accept) h(call) r(.) 76 b(It) 39 b(shou) n(ld) p Fd +63 4244 a(clo) n(se\(l) n(isten) n(Sock) n(\)) p Fg(,) 22 +b(tidy) g(up) g(as) h(necessary) e(and) i(exit.) 204 +4367 y(On) 30 b(Solaris) f(2.5) i(thr) n(ead) e(B) g(can't) h(do) p +Fd 29 w(shu) n(tdow) n(n\(lis) n(tenS) n(ock,2) n(\)) p +Fg 29 w(\227) g(this) f(r) n(eturns) p Fd 63 4480 a(ENO) n(TCON) n(N) p +Fg(.) 22 b(Instead) f(the) h(following) h(strateg) n(y) g(can) g(be) g +(used) n(:) 204 4603 y(First) 35 b(thr) n(ead) h(B) g(set) n(s) g(some) +f(sort) g(of) h("shutdo) n(wn) g(\003ag") g(associated) g(with) g +(listenSock.) 63 4716 y(Then) 31 b(it) h(does) p Fd 30 +w(gets) n(ocka) n(ddr\(l) n(iste) n(nSock) n(\)) p Fg +32 w(to) f(\002nd) g(out) g(which) i(port) e(listenSock) f(is) 63 +4828 y(on) 18 b(\(or) h(knows) e(alr) n(eady\),) j(sets) d(up) h(a) h +(socket) e(dummySock,) i(doe) n(s) p Fd 19 w(con) n(nect) n(\(dumm) n +(ySoc) n(k,) 63 4941 y(thi) n(s) 54 b(host,) f(por) n(t\)) p +Fg 22 w(and) 23 b(\002nally) g(does) p Fd 21 w(clos) n(e\(dum) n(mySo) n +(ck\)) p Fg(.) 204 5064 y(Wher) n(ever) 16 b(thr) n(ead) h(A) g(is) g +(in) h(the) e(loop,) h(eventually) g(it) h(will) g(call) p +Fd 19 w(acce) n(pt\(li) n(sten) n(Sock) n(\)) p Fg(.) 63 +5177 y(This) 35 b(will) j(r) n(eturn) d(successfully) g(with) h(a) h +(new) e(socket,) j(say) e(connSock.) 67 b(Thr) n(ead) 36 +b(A) f(then) 63 5290 y(checks) 20 b(to) h(see) f(if) i(the) f("shutd) n +(own) g(\003ag") h(is) f(set.) 26 b(If) c(not,) e(then) h(it's) g(a) h +(normal) g(connection.) 27 b(If) 21 b(it) 63 5403 y(is) h(set,) g(then) +f(thr) n(ead) h(A) h(closes) f(listenSock) f(and) i(connSock,) e +(tidies) h(up) g(and) h(exits.) p 90 rotate dyy eop +%%Page: 6 6 +6 5 bop Fg 221 249 a(6) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23 +b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fc 221 548 a(6.3) 99 +b(write\(\)) p Fg 221 768 a(Thr) n(ead) 19 b(A) f(may) h(be) g(blocked) +f(in) i(write,) f(or) f(about) h(to) f(go) g(in) h(to) g(a) g(poten) n +(tiall) r(y-blocking) g(write.) 221 881 y(Thr) n(ead) j(B) h(wants) f +(to) g(shut) f(it) i(down.) 362 1016 y(On) g(Solaris) g(2.5:) 362 +1150 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n(\(soc) n +(k,2\)) p Fg -2 w(.) 362 1285 y(If) c(thr) n(ead) f(A) h(is) g(alr) n +(eady) g(in) p Fd 20 w(wri) n(te\(s) n(ock\)) p Fg 17 +w(then) f(it) h(will) i(r) n(eturn) d(with) p Fd 18 w(ENXIO) p +Fg -2 w(.) h(If) g(thr) n(ead) 221 1398 y(A) k(calls) h(write) e(after) +g(thr) n(ead) g(B) h(calls) h(shut) n(down) e(this) g(will) i(r) n +(eturn) p Fd 22 w(EIO) p Fg(.) 362 1532 y(On) f(Digital) h(Unix) f +(3.2:) 362 1666 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 +w(shu) n(tdown) n(\(soc) n(k,2\)) p Fg -2 w(.) 362 1801 +y(If) h(thr) n(ead) f(A) g(is) h(alr) n(eady) g(in) p +Fd 24 w(writ) n(e\(so) n(ck\)) p Fg 23 w(then) e(it) i(will) h(r) n +(eturn) e(the) f(number) i(of) f(bytes) 221 1914 y(written) 31 +b(befor) n(e) h(it) g(became) g(blocked.) 55 b(A) 32 +b(subseq) n(uent) f(cal) r(l) h(to) f(write) h(will) h(then) e(gene) n +(rate) p Fd 221 2027 a(SIGP) n(IPE) p Fg 22 w(\(or) p +Fd 22 w(EPIP) n(E) p Fg 23 w(will) 24 b(be) e(r) n(eturned) f(if) p +Fd 24 w(SIG) n(PIPE) p Fg 21 w(is) i(ignor) n(ed) e(by) i(the) f(thr) n +(ead\).) p Fc 221 2413 a(6.4) 99 b(connect\(\)) p Fg +221 2634 a(Thr) n(ead) 30 b(A) f(may) h(be) g(blocked) f(in) i +(connect,) g(or) e(about) h(to) f(go) g(in) i(to) e(a) h(poten) n +(tiall) r(y-blocking) 221 2747 y(connect.) d(Thr) n(ead) c(B) f(wants) g +(to) g(shut) g(it) g(down.) 362 2881 y(On) h(Digital) h(Unix) f(3.2:) +362 3016 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n +(\(soc) n(k,2\)) p Fg -2 w(.) 362 3150 y(If) j(thr) n(ead) f(A) g(is) h +(alr) n(eady) g(in) p Fd 26 w(conn) n(ect\() n(sock) n(\)) p +Fg 26 w(then) e(it) i(will) h(r) n(eturn) e(a) h(successful) f(con-) 221 +3263 y(nection.) 54 b(Subsequ) n(ent) 31 b(r) n(eading) g(or) g +(writing) g(will) i(show) d(that) i(the) e(socket) g(has) h(been) g +(shut) 221 3376 y(down) 22 b(\(i.e.) 28 b(r) n(ead) 23 +b(r) n(eturns) e(0,) i(write) f(generate) n(s) p Fd 23 +w(SIG) n(PIPE) p Fg 21 w(or) g(r) n(eturns) p Fd 22 w(EPI) n(PE) p +Fg(\).) g(If) h(thr) n(ead) f(A) 221 3489 y(call) r(s) g(connect) g +(after) h(thr) n(ead) f(B) g(call) r(s) g(shutdo) n(wn) h(this) f(will) +i(r) n(eturn) p Fd 22 w(EIN) n(VAL) p Fg(.) 362 3623 +y(On) f(Solaris) g(2.5:) 362 3758 y(Ther) n(e) 35 b(is) h(no) f(way) g +(to) g(wake) g(up) g(a) h(thr) n(ead) f(which) h(is) g(blocked) f(in) h +(connect.) 66 b(Inst) n(ead) 221 3871 y(Solaris) 33 b(for) n(ces) g(us) +f(thr) n(ough) g(a) i(ridiculous) f(pr) n(oced) n(ur) n(e) g(whichever) +g(way) g(we) f(try) g(it.) 59 b(One) 221 3984 y(way) 23 +b(is) f(this:) 362 4118 y(First) d(thr) n(ead) h(A) g(cr) n(eates) f(a) +h(pipe) g(in) g(addition) g(to) f(the) g(socket) n(.) 27 +b(Instead) 19 b(of) h(shut) n(ting) g(down) 221 4231 +y(the) i(socket) n(,) h(thr) n(ead) f(B) g(simply) h(writes) e(a) i +(byte) f(to) g(the) g(pipe.) 362 4365 y(Thr) n(ead) 17 +b(A) g(meanwhile) h(set) n(s) f(the) g(socke) n(t) g(to) g +(non-blocking) g(mode) f(using) p Fd 17 w(fcn) n(tl\(s) n(ock,) 221 +4478 y(F_SE) n(TFL,) 53 b(O_NO) n(NBLO) n(CK\)) p Fg(.) 26 +b(Then) h(it) g(cal) r(ls) g(connect) g(on) g(the) f(socket) g(\227) h +(this) g(will) i(r) n(eturn) p Fd 221 4591 a(EINP) n(ROGRE) n(SS) p +Fg(.) k(Then) h(it) h(must) e(cal) r(l) p Fd 35 w(sel) n(ect\() n(\)) p +Fg(,) k(waiting) e(for) f(either) g(sock) g(to) f(become) 221 +4704 y(writable) 39 b(or) f(for) h(the) e(pipe) h(to) g(become) g(r) n +(eadable.) 75 b(If) 39 b(select) e(r) n(eturns) g(that) i(just) e(sock) +h(is) 221 4817 y(writable) 30 b(then) f(the) g(connection) g(has) h +(succeede) n(d.) 49 b(It) 29 b(then) g(need) n(s) h(to) f(set) f(the) h +(socket) f(back) 221 4930 y(to) i(blocking) h(mode) f(using) p +Fd 30 w(fcnt) n(l\(so) n(ck,) 54 b(F_S) n(ETFL) n(,) h(0\)) p +Fg(.) c(If) 31 b(instead) e(select) h(r) n(eturns) 221 +5043 y(that) 23 b(the) e(pipe) h(is) h(r) n(eadable,) g(thr) n(ead) f +(A) h(closes) e(the) h(socket) n(,) h(tidies) f(up) g(and) h(exits.) 362 +5177 y(An) g(alternative) h(method) e(is) i(similar) h(but) e(to) g +(use) f(polling) i(instead) e(of) i(the) e(pipe.) 29 +b(Thr) n(ead) 221 5290 y(B) 24 b(justs) e(sets) g(a) j(\003ag) f(and) g +(thr) n(ead) f(A) h(calls) h(select) e(with) g(a) i(timeout,) e(period) +n(ica) r(lly) h(waking) f(up) 221 5403 y(to) f(see) g(if) h(the) f +(\003ag) h(has) f(been) g(set.) p 90 rotate dyy eop +%%Page: 7 7 +7 6 bop Fe 63 249 a(REF) n(ERENCES) p Fg 2660 w(7) p +Fh 63 548 a(Refere) n(nces) p Fg 63 759 a([POSIX94]) p +Fa 46 w(Portable) 29 b(Operat) r(ing) f(System) g(Interface) h +(\(POSIX\)) e(Thr) n(ea) r(ds) h(Extension) p Fg(,) h(P1003) r(.1c) 245 +872 y(Draft) 23 b(10,) g(IEEE,) e(Septe) n(mber) i(1994) r(.) 63 +1059 y([Birr) n(ell89]) p Fa 47 w(An) 28 b(Intr) n(od) r(uction) g(to) h +(Pr) n(ogr) r(amming) g(with) g(Thr) n(ead) r(s) p Fg(,) h(Rese) n(ar) n +(ch) g(Repo) n(rt) e(35,) j(DEC) 245 1172 y(Syst) n(ems) 22 +b(Resear) n(ch) g(Center) -7 b(,) 22 b(Palo) h(Alto,) f(CA,) h(January) +g(1989) r(.) p 90 rotate dyy eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/docs/doxygen/other/shared_ptr_docstub.h b/docs/doxygen/other/shared_ptr_docstub.h new file mode 100755 index 000000000..428dd03f1 --- /dev/null +++ b/docs/doxygen/other/shared_ptr_docstub.h @@ -0,0 +1,24 @@ +namespace boost +{ + /*! + * \brief shared_ptr documentation stub + * + * \warning + * This isn't the real shared_ptr template. It's just enough to get doxygen + * to draw pretty collaboration diagrams. + * + * An enhanced relative of scoped_ptr with reference counted copy semantics. + * The object pointed to is deleted when the last shared_ptr pointing to it + * is destroyed or reset. + */ + +template class shared_ptr +{ +public: + + T * px; // contained pointer + +}; // shared_ptr + + +} // namespace boost diff --git a/docs/doxygen/other/tv-channel-frequencies b/docs/doxygen/other/tv-channel-frequencies new file mode 100644 index 000000000..e2780eca9 --- /dev/null +++ b/docs/doxygen/other/tv-channel-frequencies @@ -0,0 +1,79 @@ +# These are the center frequencies in MHz for North American broadcast +# TV channels. Each channel is 6 MHz wide, hence the bottom edge of the +# channel is 3 MHz below the value in this table. +# +# For NTSC (Analog) TV, the picture carrier is 1.25 MHz up from the +# bottom edge. NTSC has the FM audio at bottom + 5.75 and the spike is easily +# visible. +# +# For ATSC, the pilot tone is 0.31 MHz up from the bottom. +# +# + 2 57.00 + 3 63.00 + 4 69.00 + 5 79.00 + 6 85.00 + 7 177.00 + 8 183.00 + 9 189.00 + 10 195.00 + 11 201.00 + 12 207.00 + 13 213.00 + 14 473.00 + 15 479.00 + 16 485.00 + 17 491.00 + 18 497.00 + 19 503.00 + 20 509.00 + 21 515.00 + 22 521.00 + 23 527.00 + 24 533.00 + 25 539.00 + 26 545.00 + 27 551.00 + 28 557.00 + 29 563.00 + 30 569.00 + 31 575.00 + 32 581.00 + 33 587.00 + 34 593.00 + 35 599.00 + 36 605.00 + 37 611.00 + 38 617.00 + 39 623.00 + 40 629.00 + 41 635.00 + 42 641.00 + 43 647.00 + 44 653.00 + 45 659.00 + 46 665.00 + 47 671.00 + 48 677.00 + 49 683.00 + 50 689.00 + 51 695.00 + 52 701.00 + 53 707.00 + 54 713.00 + 55 719.00 + 56 725.00 + 57 731.00 + 58 737.00 + 59 743.00 + 60 749.00 + 61 755.00 + 62 761.00 + 63 767.00 + 64 773.00 + 65 779.00 + 66 785.00 + 67 791.00 + 68 797.00 + 69 803.00 diff --git a/docs/doxygen/other/vector_docstub.h b/docs/doxygen/other/vector_docstub.h new file mode 100644 index 000000000..139ce651d --- /dev/null +++ b/docs/doxygen/other/vector_docstub.h @@ -0,0 +1,16 @@ +namespace std +{ + /*! + * \brief vector documentation stub + * + * \warning + * This isn't the real vector template. It's just enough to get doxygen + * to draw pretty collaboration diagrams. + */ + template class vector + { + public: + T *p; + }; + +} // namespace std -- cgit From ed236703145cb56e7e69c5605c5fbf01a1ab3878 Mon Sep 17 00:00:00 2001 From: eb Date: Fri, 22 May 2009 16:11:15 +0000 Subject: doc fixes! work-in-progress git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11085 221aa14e-8319-0410-a670-987f0aec2ac5 --- docs/doxygen/other/group_defs.dox | 86 ++++++++++++++------------------------- 1 file changed, 31 insertions(+), 55 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 7373236ce..44f436393 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -1,67 +1,43 @@ /*! - * \defgroup block Signal Processing Blocks - * These are the signal processing blocks... + * \defgroup block GNU Radio C++ Signal Processing Blocks + * \brief All C++ blocks that can be used in GR graphs are listed here or in + * the subcategories below. + * + * Sorry, at this time the Python hierarchical blocks are not included + * in this index. * @{ */ -/*! - * \defgroup source Signal Sources - * signal sources docs... - */ - -/*! - * \defgroup sink Signal Sinks - * docs for sinks... - */ - -/*! - * \defgroup filter Filters - */ +/*! \defgroup container_blk Top Block and Hierarchical Block Base Classes */ +/*! \defgroup source_blk Signal Sources */ +/*! \defgroup sink_blk Signal Sinks */ +/*! \defgroup filter_blk Filters */ +/*! \defgroup math_blk Mathematics */ +/*! \defgroup modulation_blk Signal Modulation */ +/*! \defgroup demodulation_blk Signal Demodulation */ +/*! \defgroup coding_blk Information Coding and Decoding*/ +/*! \defgroup synch_blk Synchronization */ +/*! \defgroup eq_blk Equalization */ +/*! \defgroup converter_blk Type Conversions */ +/*! \defgroup level_blk Signal Level Control (AGC) */ +/*! \defgroup dft_blk Fourier Transform */ +/*! \defgroup wavelet_blk Wavelet Transform */ +/*! \defgroup misc_blk Miscellaneous Blocks */ +/*! \defgroup slicedice_blk Slicing and Dicing Streams */ +/*! \defgroup vocoder_blk Voice Encoders and Decoders */ -/*! - * \defgroup converter Type Conversions +/*! + * \defgroup base_blk Base classes for GR Blocks + * \brief All C++ blocks are derived from these base classes */ -/*! - * \defgroup level Signal Level Control - */ - -/*! - * \defgroup clock Signal Clock Synchronization - */ - -/*! - * \defgroup dft Fourier Transformation - */ - -/*! - * \defgroup synch Synchronization - */ - -/*! - * \defgroup packet Packetization - */ - -/*! - * \defgroup logic Logical - */ /*! @} */ -/*! \defgroup filter_design Digital Filter Design */ -/*! \defgroup graphical Graphical Utilities */ -/*! \defgroup encdec Voice Encoders and Decoders */ -/*! \defgroup coding Information Coding and Decoding */ -/*! \defgroup modulation Signal Modulation */ -/*! \defgroup demodulation Signal Demodulation */ -/*! \defgroup flow Samples Flow Control */ - -/*! \defgroup math Mathmatics */ -/*! \defgroup tools Tools */ -/*! \defgroup misc Miscellaneous */ +/*! \defgroup filter_design Digital Filter Design */ +/*! \defgroup misc Miscellaneous */ /*! \defgroup internal Implementation Details */ -/*! \defgroup base Misc Common Base Classes */ /*! * \defgroup applications Applications * These are some applications build using gnuradio... @@ -90,6 +66,6 @@ /*! @} */ -/*! \defgroup usrp USRP */ -/*! \defgroup usrp2 USRP2 */ -/*! \defgroup hardware Hardware */ +/*! \defgroup usrp USRP */ +/*! \defgroup usrp2 USRP2 */ +/*! \defgroup hardware Misc Hardware Control */ -- cgit From 5a4b9ba9af590b2a269cb3e5872c85faa7c284d1 Mon Sep 17 00:00:00 2001 From: eb Date: Fri, 22 May 2009 21:22:22 +0000 Subject: Doc fixes. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11088 221aa14e-8319-0410-a670-987f0aec2ac5 --- docs/doxygen/other/group_defs.dox | 18 ++++++++++++------ docs/doxygen/other/main_page.dox | 7 +++++++ 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 44f436393..6f2e1ac7f 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -16,12 +16,14 @@ /*! \defgroup modulation_blk Signal Modulation */ /*! \defgroup demodulation_blk Signal Demodulation */ /*! \defgroup coding_blk Information Coding and Decoding*/ -/*! \defgroup synch_blk Synchronization */ +/*! \defgroup sync_blk Synchronization */ /*! \defgroup eq_blk Equalization */ /*! \defgroup converter_blk Type Conversions */ /*! \defgroup level_blk Signal Level Control (AGC) */ /*! \defgroup dft_blk Fourier Transform */ /*! \defgroup wavelet_blk Wavelet Transform */ +/*! \defgroup ofdm_blk OFDM Blocks */ +/*! \defgroup pager_blk Pager Blocks */ /*! \defgroup misc_blk Miscellaneous Blocks */ /*! \defgroup slicedice_blk Slicing and Dicing Streams */ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ @@ -59,13 +61,17 @@ * Pager Applications */ -/*! - * \defgroup sounder Sounder - * Channel Sounder - */ - /*! @} */ /*! \defgroup usrp USRP */ /*! \defgroup usrp2 USRP2 */ + +/*! + * \defgroup gcell gcell: Cell Broadband Engine SPE Scheduler & RPC Mechanism + * + * For additional information please see the + * gcell wiki page + * and gcell-sdrf-2008.pdf. + */ + /*! \defgroup hardware Misc Hardware Control */ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 5c37905fa..43fcbf67a 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -2,4 +2,11 @@ Welcome to GNU Radio! +For a list of all GNU Radio C++ blocks, please see C++ Blocks. + +Please note that at this time, we haven't found an acceptable way to +provide unified documentation for the C++ parts of the system and the +parts written in Python (mostly hierarchical blocks). Until this gets +worked out, please bear with us, or better yet, solve it for us! + */ -- cgit From 253018c6cdb114f5662a2d7ba8ed748c6e68e3a7 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 14 Aug 2009 18:10:11 +0000 Subject: Added git ignore files auto created from svn:ignore properties. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11592 221aa14e-8319-0410-a670-987f0aec2ac5 --- docs/doxygen/other/.gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/doxygen/other/.gitignore (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/.gitignore b/docs/doxygen/other/.gitignore new file mode 100644 index 000000000..a02b6ff73 --- /dev/null +++ b/docs/doxygen/other/.gitignore @@ -0,0 +1,8 @@ +/Makefile +/Makefile.in +/.la +/.lo +/.deps +/.libs +/*.la +/*.lo -- cgit From 8e4bed09059a00767a8aa1cb9800059aecde52ab Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Mon, 8 Feb 2010 15:13:14 -0800 Subject: Regenerate defective omnithread.pdf Thanks to Dimitris Symeonidis for pointing out the problem and solution. --- docs/doxygen/other/omnithread.pdf | Bin 126474 -> 44848 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/omnithread.pdf b/docs/doxygen/other/omnithread.pdf index b54218744..b0033072f 100644 Binary files a/docs/doxygen/other/omnithread.pdf and b/docs/doxygen/other/omnithread.pdf differ -- cgit From c6ad778bda302a9abfe3f1a905d1a80ee34c60a6 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Mon, 26 Apr 2010 23:14:12 -0700 Subject: Remove omnithreads library. --- docs/doxygen/other/Makefile.am | 5 +- docs/doxygen/other/omnithread.html | 411 --------------------- docs/doxygen/other/omnithread.pdf | Bin 44848 -> 0 bytes docs/doxygen/other/omnithread.ps | 730 ------------------------------------- 4 files changed, 1 insertion(+), 1145 deletions(-) delete mode 100644 docs/doxygen/other/omnithread.html delete mode 100644 docs/doxygen/other/omnithread.pdf delete mode 100644 docs/doxygen/other/omnithread.ps (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/Makefile.am b/docs/doxygen/other/Makefile.am index 5e05d5d36..eb5f170af 100644 --- a/docs/doxygen/other/Makefile.am +++ b/docs/doxygen/other/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2004 Free Software Foundation, Inc. +# Copyright 2001,2004,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -24,9 +24,6 @@ include $(top_srcdir)/Makefile.common EXTRA_DIST = \ doxypy.py \ group_defs.dox \ - omnithread.html \ - omnithread.pdf \ - omnithread.ps \ shared_ptr_docstub.h \ tv-channel-frequencies \ vector_docstub.h diff --git a/docs/doxygen/other/omnithread.html b/docs/doxygen/other/omnithread.html deleted file mode 100644 index 5682d1d0b..000000000 --- a/docs/doxygen/other/omnithread.html +++ /dev/null @@ -1,411 +0,0 @@ - - -The OMNI Thread Abstraction - - - - - - - - - - - - -

The OMNI Thread Abstraction

- -

Tristan Richardson
-AT&T Laboratories Cambridge
-

- -

Revised November 2001

- - -

1  Introduction

- -The OMNI thread abstraction is designed to provide a common set of -thread operations for use in programs written in C++. Programs -written using the abstraction should be much easier to port between -different architectures with different underlying threads primitives.
-
-The programming interface is designed to be similar to the C language -interface to POSIX threads (IEEE draft standard 1003.1c --- previously -1003.4a, often known as ``pthreads'' [POSIX94]).
-
-Much of the abstraction consists of simple C++ object wrappers around -pthread calls. However for some features such as thread-specific -data, a better interface can be offered because of the use of C++.
-
-Some of the more complex features of pthreads are not supported -because of the difficulty of ensuring the same features can be offered -on top of other thread systems. Such features include thread -cancellation and complex scheduling control (though simple thread -priorities are supported).
-
-The abstraction layer is currently implemented for the following -architectures / thread systems: -
  • Solaris 2.x using pthreads draft 10 -
  • Solaris 2.x using solaris threads (but pthreads version is now standard) -
  • Alpha OSF1 using pthreads draft 4 -
  • Windows NT using NT threads -
  • Linux 2.x using Linuxthread 0.5 (which is based on pthreads draft 10) -
  • Linux 2.x using MIT pthreads (which is based on draft 8) -
  • ATMos using pthreads draft 6 (but not Virata ATMos)
-See the omnithread.h header file for full details of the API. -The descriptions below assume you have some previous knowledge of -threads, mutexes, condition variables and semaphores. Also refer to -other documentation ([Birrell89], [POSIX94]) for further -explanation of these ideas (particularly condition variables, the use -of which may not be particularly intuitive when first encountered).
-
- - -

2  Synchronisation objects

- -Synchronisation objects are used to synchronise threads within the -same process. There is no inter-process synchronisation provided. -The synchronisation objects provided are mutexes, condition variables -and counting semaphores.
-
- - -

2.1  Mutex

- -An object of type omni_mutex is used for mutual exclusion. -It provides two operations, lock() and unlock(). -The alternative names acquire() and release() can be -used if preferred. Behaviour is undefined when a thread attempts to -lock the same mutex again or when a mutex is locked by one thread and -unlocked by a different thread.
-
- - -

2.2  Condition Variable

- -A condition variable is represented by an omni_condition and -is used for signalling between threads. A call to wait() -causes a thread to wait on the condition variable. A call to -signal() wakes up at least one thread if any are waiting. A -call to broadcast() wakes up all threads waiting on the -condition variable.
-
-When constructed, a pointer to an omni_mutex must be given. -A condition variable wait() has an implicit mutex -unlock() and lock() around it. The link between -condition variable and mutex lasts for the lifetime of the condition -variable (unlike pthreads where the link is only for the duration of -the wait). The same mutex may be used with several condition -variables.
-
-A wait with a timeout can be achieved by calling -timed_wait(). This is given an absolute time to wait until. -The routine omni_thread::get_time() can be used to turn a -relative time into an absolute time. timed_wait() returns -true if the condition was signalled, false if the -time expired before the condition variable was signalled.
-
- - -

2.3  Counting semaphores

- -An omni_semaphore is a counting semaphore. When created it -is given an initial unsigned integer value. When wait() is -called, the value is decremented if non-zero. If the value is zero -then the thread blocks instead. When post() is called, if -any threads are blocked in wait(), exactly one thread is -woken. If no threads were blocked then the value of the semaphore is -incremented.
-
-If a thread calls try_wait(), then the thread won't block if -the semaphore's value is 0, returning false instead.
-
-There is no way of querying the value of the semaphore.
-
- - -

3  Thread object

- -A thread is represented by an omni_thread object. There are -broadly two different ways in which it can be used.
-
-The first way is simply to create an omni_thread object, -giving a particular function which the thread should execute. This is -like the POSIX (or any other) C language interface.
-
-The second method of use is to create a new class which inherits from -omni_thread. In this case the thread will execute the -run() member function of the new class. One advantage of -this scheme is that thread-specific data can be implemented simply by -having data members of the new class.
-
-When constructed a thread is in the "new" state and has not actually -started. A call to start() causes the thread to begin -executing. A static member function create() is provided to -construct and start a thread in a single call. A thread exits by -calling exit() or by returning from the thread function.
-
-Threads can be either detached or undetached. Detached threads are -threads for which all state will be lost upon exit. Other threads -cannot determine when a detached thread will disappear, and therefore -should not attempt to access the thread object unless some explicit -synchronisation with the detached thread guarantees that it still -exists.
-
-Undetached threads are threads for which storage is not reclaimed -until another thread waits for its termination by calling -join(). An exit value can be passed from an undetached -thread to the thread which joins it.
-
-Detached / undetached threads are distinguished on creation by the -type of function they execute. Undetached threads execute a function -which has a void* return type, whereas detached threads -execute a function which has a void return type. -Unfortunately C++ member functions are not allowed to be distinguished -simply by their return type. Thus in the case of a derived class of -omni_thread which needs an undetached thread, the member -function executed by the thread is called run_undetached() -rather than run(), and it is started by calling -start_undetached() instead of start().
-
-The abstraction currently supports three priorities of thread, but no -guarantee is made of how this will affect underlying thread -scheduling. The three priorities are PRIORITY_LOW, -PRIORITY_NORMAL and PRIORITY_HIGH. By default all -threads run at PRIORITY_NORMAL. A different priority can be -specified on thread creation, or while the thread is running using -set_priority(). A thread's current priority is returned by -priority().
-
-Other functions provided are self() which returns the calling -thread's omni_thread object, yield() which -requests that other threads be allowed to run, id() which -returns an integer id for the thread for use in debugging, -state(), sleep() and get_time().
-
- - -

4  Per-thread data

- -omnithread supports per-thread data, via member functions of the -omni_thread object.
-
-First, you must allocate a key for with the -omni_thread::allocate_key() function. Then, any object -whose class is derived from omni_thread::value_t can be -stored using the set_value() function. Values are retrieved -or removed with get_value() and remove_value() -respectively.
-
-When the thread exits, all per-thread data is deleted (hence the base -class with virtual destructor).
-
-Note that the per-thread data functions are not thread safe, -so although you can access one thread's storage from another thread, -there is no concurrency control. Unless you really know what you are -doing, it is best to only access per-thread data from the thread it is -attached to.
-
- - -

5  Using OMNI threads in your program

- -Obviously you need to include the omnithread.h header file in -your source code, and link in the omnithread library with your -executable. Because there is a single omnithread.h for all -platforms, certain preprocessor defines must be given as compiler -options. The easiest way to do this is to study the makefiles given -in the examples provided with this distribution. If you are to -include OMNI threads in your own development environment, these are -the necessary preprocessor defines:
- - - - - - - - - - - - - - - - - - - - - - - - -
PlatformPreprocessor Defines
Sun Solaris 2.x-D__sunos__ -D__sparc__ -D__OSVERSION__=5
 -DSVR4 -DUsePthread -D_REENTRANT
x86 Linux 2.0-D__linux__ -D__i86__ -D__OSVERSION__=2
with linuxthreads 0.5-D_REENTRANT
Digital Unix 3.2-D__osf1__ -D__alpha__ -D__OSVERSION__=3
 -D_REENTRANT
Windows NT-D__NT__ -MD

- - -

6  Threaded I/O shutdown for Unix

- -or, how one thread should tell another thread to shut down when it -might be doing a blocking call on a socket.
-
-If you are using omniORB, you don't need to worry about all -this, since omniORB does it for you. This section is only relevant -if you are using omnithread in your own socket-based programming. It -is also seriously out of date.
-
-Unfortunately there doesn't seem to be a standard way of doing this -which works across all Unix systems. I have investigated the -behaviour of Solaris 2.5 and Digital Unix 3.2. On Digital Unix -everything is fine, as the obvious method using shutdown() seems to -work OK. Unfortunately on Solaris shutdown can only be used on a -connected socket, so we need devious means to get around this -limitation. The details are summarised below:
-
- - -

6.1  read()

- -Thread A is in a loop, doing read(sock), processing the data, -then going back into the read.
-
-Thread B comes along and wants to shut it down --- it can't cancel -thread A since (i) working out how to clean up according to where A is -in its loop is a nightmare, and (ii) this isn't available in -omnithread anyway.
-
-On Solaris 2.5 and Digital Unix 3.2 the following strategy works:
-
-Thread B does shutdown(sock,2).
-
-At this point thread A is either blocked inside read(sock), or -is elsewhere in the loop. If the former then read will return 0, -indicating that the socket is closed. If the latter then eventually -thread A will call read(sock) and then this will return 0. -Thread A should close(sock), do any other tidying up, and exit.
-
-If there is another point in the loop that thread A can block then -obviously thread B needs to be aware of this and be able to wake it up -in the appropriate way from that point.
-
- - -

6.2  accept()

- -Again thread A is in a loop, this time doing an accept on listenSock, -dealing with a new connection and going back into accept. Thread B -wants to cancel it.
-
-On Digital Unix 3.2 the strategy is identical to that for read:
-
-Thread B does shutdown(listenSock,2). Wherever thread A is in -the loop, eventually it will return ECONNABORTED from the -accept call. It should close(listenSock), tidy up as necessary -and exit.
-
-On Solaris 2.5 thread B can't do shutdown(listenSock,2) --- -this returns ENOTCONN. Instead the following strategy can be -used:
-
-First thread B sets some sort of "shutdown flag" associated with -listenSock. Then it does getsockaddr(listenSock) to find out -which port listenSock is on (or knows already), sets up a socket -dummySock, does connect(dummySock, this host, port) and -finally does close(dummySock).
-
-Wherever thread A is in the loop, eventually it will call -accept(listenSock). This will return successfully with a new -socket, say connSock. Thread A then checks to see if the "shutdown -flag" is set. If not, then it's a normal connection. If it is set, -then thread A closes listenSock and connSock, tidies up and exits.
-
- - -

6.3  write()

- -Thread A may be blocked in write, or about to go in to a -potentially-blocking write. Thread B wants to shut it down.
-
-On Solaris 2.5:
-
-Thread B does shutdown(sock,2).
-
-If thread A is already in write(sock) then it will return with -ENXIO. If thread A calls write after thread B calls shutdown -this will return EIO.
-
-On Digital Unix 3.2:
-
-Thread B does shutdown(sock,2).
-
-If thread A is already in write(sock) then it will return the -number of bytes written before it became blocked. A subsequent call -to write will then generate SIGPIPE (or EPIPE will be -returned if SIGPIPE is ignored by the thread).
-
- - -

6.4  connect()

- -Thread A may be blocked in connect, or about to go in to a -potentially-blocking connect. Thread B wants to shut it down.
-
-On Digital Unix 3.2:
-
-Thread B does shutdown(sock,2).
-
-If thread A is already in connect(sock) then it will return a -successful connection. Subsequent reading or writing will show that -the socket has been shut down (i.e. read returns 0, write generates -SIGPIPE or returns EPIPE). If thread A calls connect -after thread B calls shutdown this will return EINVAL.
-
-On Solaris 2.5:
-
-There is no way to wake up a thread which is blocked in connect. -Instead Solaris forces us through a ridiculous procedure whichever way -we try it. One way is this:
-
-First thread A creates a pipe in addition to the socket. Instead of -shutting down the socket, thread B simply writes a byte to the pipe.
-
-Thread A meanwhile sets the socket to non-blocking mode using -fcntl(sock, F_SETFL, O_NONBLOCK). Then it calls connect -on the socket --- this will return EINPROGRESS. Then it must -call select(), waiting for either sock to become writable or -for the pipe to become readable. If select returns that just sock is -writable then the connection has succeeded. It then needs to set the -socket back to blocking mode using fcntl(sock, F_SETFL, 0). If -instead select returns that the pipe is readable, thread A closes the -socket, tidies up and exits.
-
-An alternative method is similar but to use polling instead of the -pipe. Thread B justs sets a flag and thread A calls select with a -timeout, periodically waking up to see if the flag has been set.
-
- - -

References

-
[POSIX94]
-Portable Operating System Interface (POSIX) Threads Extension, -P1003.1c Draft 10, -IEEE, -September 1994.
-
-
[Birrell89]
-An Introduction to Programming with Threads, -Research Report 35, -DEC Systems Research Center, -Palo Alto, CA, -January 1989.
- - - -
-
This document was translated from LATEX by -HEVEA. -
- - diff --git a/docs/doxygen/other/omnithread.pdf b/docs/doxygen/other/omnithread.pdf deleted file mode 100644 index b0033072f..000000000 Binary files a/docs/doxygen/other/omnithread.pdf and /dev/null differ diff --git a/docs/doxygen/other/omnithread.ps b/docs/doxygen/other/omnithread.ps deleted file mode 100644 index 9e858f0b7..000000000 --- a/docs/doxygen/other/omnithread.ps +++ /dev/null @@ -1,730 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvipsk 5.86 p1.5d Copyright 1996-2001 ASCII Corp.(www-ptex@ascii.co.jp) -%%based on dvipsk 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com) -%%Title: omnithread.dvi -%%Pages: 7 -%%PageOrder: Ascend -%%BoundingBox: 0 0 596 842 -%%DocumentFonts: Palatino-Roman Palatino-Italic Palatino-Bold Courier -%%EndComments -%DVIPSWebPage: (www.radicaleye.com) -%DVIPSCommandLine: dvips omnithread -%DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2002.08.15:1756 -%%BeginProcSet: texc.pro -%! -/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S -N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 -mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 -0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ -landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize -mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ -matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round -exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ -statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] -N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin -/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array -/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 -array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N -df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A -definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get -}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} -B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr -1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 -1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx -0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx -sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ -rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp -gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B -/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ -/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ -A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy -get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} -ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp -fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 -{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add -chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ -1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} -forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn -/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put -}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ -bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A -mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ -SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ -userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X -1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 -index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N -/dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3 -def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 -rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 -N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop -false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A -length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse} -forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{ -BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat -{BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch -round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 -rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B -/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M} -B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p --3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{ -0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end - -%%EndProcSet -%%BeginProcSet: 8r.enc -% @@psencodingfile@{ -% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", -% version = "0.6", -% date = "1 July 1998", -% filename = "8r.enc", -% email = "tex-fonts@@tug.org", -% docstring = "Encoding for TrueType or Type 1 fonts -% to be used with TeX." -% @} -% -% Idea is to have all the characters normally included in Type 1 fonts -% available for typesetting. This is effectively the characters in Adobe -% Standard Encoding + ISO Latin 1 + extra characters from Lucida. -% -% Character code assignments were made as follows: -% -% (1) the Windows ANSI characters are almost all in their Windows ANSI -% positions, because some Windows users cannot easily reencode the -% fonts, and it makes no difference on other systems. The only Windows -% ANSI characters not available are those that make no sense for -% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen -% (173). quotesingle and grave are moved just because it's such an -% irritation not having them in TeX positions. -% -% (2) Remaining characters are assigned arbitrarily to the lower part -% of the range, avoiding 0, 10 and 13 in case we meet dumb software. -% -% (3) Y&Y Lucida Bright includes some extra text characters; in the -% hopes that other PostScript fonts, perhaps created for public -% consumption, will include them, they are included starting at 0x12. -% -% (4) Remaining positions left undefined are for use in (hopefully) -% upward-compatible revisions, if someday more characters are generally -% available. -% -% (5) hyphen appears twice for compatibility with both -% ASCII and Windows. -% -/TeXBase1Encoding [ -% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) - /.notdef /dotaccent /fi /fl - /fraction /hungarumlaut /Lslash /lslash - /ogonek /ring /.notdef - /breve /minus /.notdef -% These are the only two remaining unencoded characters, so may as -% well include them. - /Zcaron /zcaron -% 0x10 - /caron /dotlessi -% (unusual TeX characters available in, e.g., Lucida Bright) - /dotlessj /ff /ffi /ffl - /.notdef /.notdef /.notdef /.notdef - /.notdef /.notdef /.notdef /.notdef - % very contentious; it's so painful not having quoteleft and quoteright - % at 96 and 145 that we move the things normally found there to here. - /grave /quotesingle -% 0x20 (ASCII begins) - /space /exclam /quotedbl /numbersign - /dollar /percent /ampersand /quoteright - /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash -% 0x30 - /zero /one /two /three /four /five /six /seven - /eight /nine /colon /semicolon /less /equal /greater /question -% 0x40 - /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O -% 0x50 - /P /Q /R /S /T /U /V /W - /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore -% 0x60 - /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o -% 0x70 - /p /q /r /s /t /u /v /w - /x /y /z /braceleft /bar /braceright /asciitilde - /.notdef % rubout; ASCII ends -% 0x80 - /.notdef /.notdef /quotesinglbase /florin - /quotedblbase /ellipsis /dagger /daggerdbl - /circumflex /perthousand /Scaron /guilsinglleft - /OE /.notdef /.notdef /.notdef -% 0x90 - /.notdef /.notdef /.notdef /quotedblleft - /quotedblright /bullet /endash /emdash - /tilde /trademark /scaron /guilsinglright - /oe /.notdef /.notdef /Ydieresis -% 0xA0 - /.notdef % nobreakspace - /exclamdown /cent /sterling - /currency /yen /brokenbar /section - /dieresis /copyright /ordfeminine /guillemotleft - /logicalnot - /hyphen % Y&Y (also at 45); Windows' softhyphen - /registered - /macron -% 0xD0 - /degree /plusminus /twosuperior /threesuperior - /acute /mu /paragraph /periodcentered - /cedilla /onesuperior /ordmasculine /guillemotright - /onequarter /onehalf /threequarters /questiondown -% 0xC0 - /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla - /Egrave /Eacute /Ecircumflex /Edieresis - /Igrave /Iacute /Icircumflex /Idieresis -% 0xD0 - /Eth /Ntilde /Ograve /Oacute - /Ocircumflex /Otilde /Odieresis /multiply - /Oslash /Ugrave /Uacute /Ucircumflex - /Udieresis /Yacute /Thorn /germandbls -% 0xE0 - /agrave /aacute /acircumflex /atilde - /adieresis /aring /ae /ccedilla - /egrave /eacute /ecircumflex /edieresis - /igrave /iacute /icircumflex /idieresis -% 0xF0 - /eth /ntilde /ograve /oacute - /ocircumflex /otilde /odieresis /divide - /oslash /ugrave /uacute /ucircumflex - /udieresis /yacute /thorn /ydieresis -] def - -%%EndProcSet -%%BeginProcSet: texps.pro -%! -TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 -index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll -exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics -exch def dict begin 0 1 255{exch dup type/integertype ne{pop pop 1 sub -dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} -ifelse}for Metrics/Metrics currentdict end def[2 index currentdict end -definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup -sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll -mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ -exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} -forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def -end - -%%EndProcSet -TeXDict begin 39158280 55380996 1000 600 600 (omnithread.dvi) -@start /Fa 134[ 45 45 66 1[ 51 30 35 35 1[ 45 40 51 71 -25 2[ 25 45 45 25 35 45 37 42 40 8[ 66 3[ 56 51 2[ 56 -71 5[ 30 3[ 56 3[ 66 23[ 30 30 40[{ TeXBase1Encoding ReEncodeFont} 31 -90.9091 /Palatino-Italic rf /Fb 134[ 51 1[ 76 1[ 56 30 -40 35 2[ 51 56 81 30 2[ 30 56 51 35 45 56 40 56 45 14[ 66 -2[ 76 5[ 35 6[ 61 19[ 23 30 23 4[ 25 39[{ TeXBase1Encoding ReEncodeFont} -27 90.9091 /Palatino-Bold rf /Fc 135[ 50 83 1[ 61 33 -44 39 1[ 61 55 61 89 33 2[ 33 61 55 1[ 50 61 44 61 50 -10[ 78 8[ 100 9[ 72 12[ 50 1[ 50 50 50 50 2[ 25 4[ 33 -33 40[{ TeXBase1Encoding ReEncodeFont} 30 99.6264 /Palatino-Bold -rf /Fd 134[ 55 55 55 55 55 55 55 55 55 55 55 55 55 55 -55 55 55 55 55 55 55 55 55 55 55 1[ 55 5[ 55 55 55 55 -55 55 55 55 1[ 55 55 55 55 55 55 1[ 55 55 55 55 55 55 -55 55 55 3[ 55 2[ 55 1[ 55 1[ 55 55 55 55 55 55 55 1[ 55 -55 55 1[ 55 55 55 40[{ TeXBase1Encoding ReEncodeFont} 65 -90.9091 /Courier rf /Fe 141[ 36 12[ 44 56 2[ 45 7[ 61 -61 91 1[ 71 56 48 61 2[ 71 76 3[ 30 31 76 1[ 51 56 70 -64 56 71 10[ 45 3[ 45 45 1[ 55 23 4[ 30 30 40[{ -.167 SlantFont TeXBase1Encoding ReEncodeFont} 29 90.9091 -/Palatino-Roman rf -%DVIPSBitmapFont: Ff cmsy10 10.95 1 -/Ff 1 16 df 15 -D E -%EndDVIPSBitmapFont -/Fg 104[ 91 2[ 45 45 24[ 45 51 47 76 51 55 30 39 36 51 -55 50 53 80 26 51 21 26 53 51 30 44 56 40 50 45 3[ 30 -1[ 30 2[ 61 91 66 71 56 48 61 1[ 55 71 76 86 56 66 30 -31 76 1[ 51 56 70 64 56 71 6[ 23 45 45 45 45 45 45 45 -45 45 45 55 23 30 23 55 1[ 30 30 25 4[ 34 30[ 55 55 2[{ -TeXBase1Encoding ReEncodeFont} 75 90.9091 /Palatino-Roman -rf /Fh 134[ 66 60 100 1[ 73 40 53 47 1[ 73 66 73 106 -2[ 40 40 73 66 47 60 73 53 73 60 11[ 93 80 73 86 1[ 73 -100 100 120 3[ 47 18[ 60 60 60 60 60 60 1[ 35 1[ 40 45[{ -TeXBase1Encoding ReEncodeFont} 38 119.552 /Palatino-Bold -rf /Fi 137[ 50 2[ 39 9[ 28 3[ 39 50 17[ 66 82[{ -TeXBase1Encoding ReEncodeFont} 6 99.6264 /Palatino-Italic -rf /Fj 137[ 56 1[ 32 42 39 2[ 54 58 88 3[ 29 58 55 1[ 48 -61 44 55 50 12[ 61 1[ 67 3[ 83 1[ 61 8[ 71 1[ 78 14[ 50 -50 50 9[ 78 38[{ TeXBase1Encoding ReEncodeFont} 25 99.6264 -/Palatino-Roman rf /Fk 139[ 47 61 57 2[ 78 83 4[ 42 83 -2[ 69 88 64 79 72 12[ 88 4[ 113 119 136 3[ 48 7[ 112 -65[{ TeXBase1Encoding ReEncodeFont} 18 143.462 /Palatino-Roman -rf end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%PaperSize: A4 - -%%EndSetup -%%Page: 1 1 -1 0 bop Fk 728 918 a(The) 36 b(OMNI) g(Thr) m(ead) f(Abstracti) n(on) p -Fj 1293 1176 a(T) -9 b(ristan) 26 b(Richar) n(dson) 1022 -1293 y(A) -7 b(T&T) 24 b(Laboratories) i(Cambridge) p -Fi 1192 1504 a(Revised) p Fj 24 w(November) f(2001) p -Fh 63 1961 a(1) 119 b(Introduction) p Fg 63 2183 a(The) 20 -b(OMNI) h(thr) n(ead) g(abstraction) g(is) h(des) n(igned) f(to) f(pr) n -(ovide) h(a) h(common) f(set) f(of) h(thr) n(ead) g(oper) n(-) 63 -2296 y(ations) h(for) g(use) g(in) h(pr) n(ograms) f(written) f(in) i -(C++.) 29 b(Pr) n(ograms) 22 b(written) g(using) f(the) h(abstraction) -63 2409 y(should) 30 b(be) g(much) i(easier) e(to) g(port) g(betwee) n -(n) h(dif) n(fer) n(ent) g(ar) n(chi) r(tectur) l(es) g(with) g(dif) n -(fer) n(ent) f(un-) 63 2522 y(derlying) 21 b(thr) n(eads) h -(primitives.) 204 2640 y(The) 17 b(pr) n(ogramming) h(interface) g(is) f -(designed) f(to) h(be) h(similar) h(to) e(the) g(C) i(language) e -(interface) 63 2753 y(to) k(POSIX) h(thr) n(eads) f(\(IEEE) g(draft) h -(standar) n(d) f(100) r(3.1c) i(\227) f(pr) n(eviously) g(1003) r(.4a,) -g(often) g(known) 63 2866 y(as) g(\223pthr) n(eads\224) h([POSIX94]\).) -204 2985 y(Much) 18 b(of) f(the) g(abstraction) i(consists) d(of) i -(simple) g(C++) g(object) g(wrappers) e(ar) n(ound) h(pthr) n(ead) 63 -3098 y(calls.) 28 b(Howe) n(ver) 20 b(for) f(some) f(featur) n(es) g -(such) h(as) h(thr) n(ead-spe) n(ci\002c) h(data,) f(a) f(better) f -(interface) i(can) 63 3211 y(be) i(of) n(fer) n(ed) g(because) h(of) f -(the) g(use) g(of) g(C++.) 204 3329 y(Some) 28 b(of) h(the) f(mor) n(e) -h(complex) f(featur) n(es) g(of) h(pthr) n(eads) f(ar) n(e) h(not) f -(suppo) n(rted) g(because) h(of) 63 3442 y(the) e(dif) n(\002culty) i -(of) f(ensuring) g(the) f(same) h(featur) n(es) g(can) h(be) f(of) n -(fer) n(ed) g(on) g(top) g(of) g(other) f(thr) n(ead) 63 -3555 y(sys) n(tems.) f(Such) 17 b(featur) n(es) g(include) h(thr) n -(ead) f(cancell) r(ation) g(and) h(complex) g(schedu) n(ling) h(contr) n -(ol) 63 3668 y(\(thoug) n(h) k(simple) g(thr) n(ead) f(priorities) g -(ar) n(e) h(supp) n(orted\).) 204 3787 y(The) i(abstraction) h(layer) h -(is) f(curr) n(ently) f(implemented) g(for) h(the) f(following) i(ar) n -(chitectur) n(es) 63 3900 y(/) 22 b(thr) n(ead) h(sys) n(tems:) p -Ff 199 4141 a(\017) p Fg 46 w(Solaris) g(2.x) g(using) f(pthr) n(eads) f -(draft) h(10) p Ff 199 4351 a(\017) p Fg 46 w(Solaris) h(2.x) g(using) f -(solaris) g(thr) n(eads) g(\(but) h(pthr) n(eads) e(version) h(is) h -(now) f(standar) n(d\)) p Ff 199 4561 a(\017) p Fg 46 -w(Alpha) h(OSF1) g(using) f(pthr) n(eads) f(draft) i(4) p -Ff 199 4772 a(\017) p Fg 46 w(W) -5 b(indows) 21 b(NT) h(using) g(NT) g -(thr) n(eads) p Ff 199 4982 a(\017) p Fg 46 w(Linux) g(2.x) h(using) f -(Linuxthr) n(ead) g(0.5) h(\(which) h(is) e(based) g(on) h(pthr) n -(eads) e(draft) i(10\)) p Ff 199 5193 a(\017) p Fg 46 -w(Linux) f(2.x) h(using) f(MIT) g(pthr) n(eads) f(\(which) j(is) f -(based) f(on) g(draft) h(8\)) p Ff 199 5403 a(\017) p -Fg 46 w(A) -7 b(TMos) 22 b(using) g(pthr) n(eads) f(draft) h(6) i -(\(but) e(not) g(V) -5 b(irata) 23 b(A) -7 b(TMos\)) 1684 -5652 y(1) p 90 rotate dyy eop -%%Page: 2 2 -2 1 bop Fg 221 249 a(2) p Fe 1797 w(2) 91 b(SYNCHRONI) n(SA) -7 -b(TION) 22 b(OBJECTS) p Fg 362 548 a(See) h(the) p Fd -22 w(omni) n(thre) n(ad.h) p Fg 22 w(header) f(\002le) i(for) f(full) i -(det) n(ail) r(s) e(of) g(the) g(API.) f(The) h(des) n(criptions) 221 -661 y(below) 35 b(assume) g(you) g(have) h(some) e(pr) n(evious) h -(knowled) n(ge) g(of) h(thr) n(eads) n(,) j(mutexes) n(,) g(condi-) 221 -774 y(tion) f(varia) r(bles) g(and) g(semaphor) n(es) n(.) 75 -b(Also) 38 b(r) n(efer) f(to) h(other) f(document) n(ation) i(\([Birr) n -(ell89) r(],) 221 887 y([POSIX94) q(]\)) 22 b(for) g(further) f -(explanation) i(of) f(thes) n(e) g(ideas) g(\(particularly) h -(condition) f(variab) r(les,) 221 1000 y(the) g(use) g(of) g(which) h -(may) g(not) f(be) h(particularly) h(intuitive) f(when) f(\002rst) f -(encounter) n(ed) n(\).) p Fh 221 1299 a(2) 119 b(Synchronisation) 31 -b(objects) p Fg 221 1510 a(Synchr) n(onisation) 26 b(objects) h(ar) n -(e) g(used) e(to) h(synchr) n(onise) g(thr) n(eads) g(within) h(the) f -(same) h(pr) n(ocess) n(.) 221 1623 y(Ther) n(e) j(is) i(no) f(inter) n -(-pr) n(ocess) f(synchr) n(onisation) g(pr) n(ovided.) 53 -b(The) 30 b(synchr) n(onisation) h(objects) 221 1735 -y(pr) n(ovided) 22 b(ar) n(e) h(mutexes) n(,) g(condition) f(variab) r -(les) g(and) h(counting) f(semaphor) n(e) n(s.) p Fc -221 1991 a(2.1) 99 b(Mutex) p Fg 221 2168 a(An) 26 b(object) g(of) h -(typ) n(e) p Fd 26 w(omni) n(_mute) n(x) p Fg 26 w(is) g(use) n(d) f -(for) h(mutual) f(exclusion.) 39 b(It) 26 b(pr) n(ovides) f(two) g(op-) -221 2281 y(erations,) p Fd 37 w(lock\() n(\)) p Fg 35 -w(and) p Fd 35 w(unloc) n(k\(\)) p Fg(.) 64 b(The) 35 -b(alternative) h(names) p Fd 35 w(acq) n(uire\() n(\)) p -Fg 35 w(and) p Fd 35 w(re-) 221 2393 y(leas) n(e\(\)) p -Fg 19 w(can) 21 b(be) f(used) f(if) i(pr) n(eferr) n(ed) n(.) 27 -b(Behaviour) 20 b(is) g(unde\002ne) n(d) g(when) f(a) i(thr) n(ead) f -(attempt) n(s) 221 2506 y(to) 30 b(lock) h(the) e(same) i(mutex) f -(again) h(or) f(when) g(a) h(mutex) f(is) h(locked) e(by) i(one) e(thr) -n(ead) h(and) h(un-) 221 2619 y(locked) 22 b(by) h(a) g(dif) n(fer) n -(ent) f(thr) n(ead.) p Fc 221 2874 a(2.2) 99 b(Condition) 26 -b(V) -11 b(ariable) p Fg 221 3051 a(A) 28 b(condition) f(varia) r(ble) h -(is) g(r) n(epr) n(ese) n(nted) f(by) h(an) p Fd 28 w(omn) n(i_con) n -(diti) n(on) p Fg 27 w(and) g(is) g(used) e(for) i(sig-) 221 -3164 y(nalli) r(ng) 20 b(betwee) n(n) g(thr) n(eads.) 26 -b(A) 21 b(call) h(to) p Fd 19 w(wait\() n(\)) p Fg 20 -w(causes) e(a) h(thr) n(ead) e(to) h(wait) h(on) f(the) f(condition) 221 -3277 y(varia) r(ble.) 45 b(A) 28 b(call) i(to) p Fd 27 -w(sign) n(al\(\)) p Fg 27 w(wakes) d(up) h(at) g(least) g(one) f(thr) n -(ead) h(if) h(any) f(ar) n(e) g(waiting.) 45 b(A) 221 -3390 y(call) 25 b(to) p Fd 22 w(bro) n(adca) n(st\(\)) p -Fg 21 w(wakes) d(up) g(all) i(thr) n(eads) e(waiting) h(on) f(the) g -(condition) g(varia) r(ble.) 362 3503 y(When) 30 b(constr) o(ucte) n -(d,) i(a) e(pointer) f(to) h(an) p Fd 30 w(omni) n(_mute) n(x) p -Fg 30 w(must) f(be) h(given.) 50 b(A) 30 b(condition) 221 -3616 y(varia) r(ble) p Fd 33 w(wait\() n(\)) p Fg 33 -w(has) j(an) h(implic) r(it) f(mutex) p Fd 33 w(unlo) n(ck\(\)) p -Fg 32 w(and) p Fd 33 w(lock) n(\(\)) p Fg 33 w(ar) n(ound) g(it.) 60 -b(The) 221 3729 y(link) 30 b(between) f(condition) g(varia) r(ble) h -(and) g(mutex) f(lasts) g(for) h(the) f(lifetime) i(of) e(the) g -(condition) 221 3842 y(varia) r(ble) c(\(unlike) h(pthr) n(eads) e -(wher) n(e) g(the) h(link) h(is) f(only) g(for) g(the) g(duration) f -(of) i(the) e(wait\).) 37 b(The) 221 3955 y(same) 23 -b(mutex) f(may) h(be) f(used) f(with) i(several) f(condition) h(variab) -r(les.) 362 4068 y(A) c(wait) g(with) g(a) g(timeout) f(can) i(be) e -(achieved) h(by) g(call) r(ing) p Fd 19 w(tim) n(ed_w) n(ait\(\)) p -Fg -2 w(.) 27 b(This) 18 b(is) h(given) 221 4181 y(an) 27 -b(absolute) e(time) h(to) f(wait) h(until.) 38 b(The) 26 -b(r) n(outine) p Fd 25 w(omn) n(i_thr) n(ead:) n(:get_) n(time) n(\(\)) -p Fg 25 w(can) h(be) 221 4293 y(used) 21 b(to) h(turn) g(a) h(r) n -(elativ) r(e) f(time) g(into) h(an) g(absolute) f(time.) p -Fd 28 w(tim) n(ed_wa) n(it\(\)) p Fg 21 w(r) n(eturns) p -Fd 21 w(true) p Fg 21 w(if) 221 4406 y(the) 27 b(condition) h(was) g -(signalled,) p Fd 29 w(false) p Fg 26 w(if) h(the) f(time) g(expir) n -(ed) f(befor) n(e) g(the) h(condition) f(vari) r(-) 221 -4519 y(able) d(was) e(signalled.) p Fc 221 4774 a(2.3) 99 -b(Counting) 26 b(semaphores) p Fg 221 4951 a(An) p Fd -21 w(omn) n(i_sem) n(apho) n(re) p Fg 20 w(is) 21 b(a) h(counting) e -(semaphor) n(e) n(.) 28 b(When) 20 b(cr) n(eated) g(it) h(is) g(given) g -(an) g(initial) 221 5064 y(unsigned) j(intege) n(r) i(value.) 36 -b(When) p Fd 25 w(wai) n(t\(\)) p Fg 24 w(is) 26 b(called,) g(the) f -(value) h(is) f(decr) n(emente) n(d) g(if) h(non-) 221 -5177 y(zer) n(o.) 43 b(If) 27 b(the) g(value) h(is) f(zer) n(o) h(then) -f(the) f(thr) n(ead) h(blocks) h(instead.) 41 b(When) p -Fd 27 w(post) n(\(\)) p Fg 27 w(is) 27 b(cal) r(led,) 221 -5290 y(if) h(any) g(thr) n(eads) e(ar) n(e) i(blocked) f(in) p -Fd 27 w(wait\() n(\)) p Fg(,) h(exactly) f(one) g(thr) n(ead) g(is) g -(woken.) 41 b(If) 27 b(no) g(thr) n(eads) 221 5403 y(wer) n(e) 22 -b(blocked) g(then) g(the) g(value) h(of) g(the) e(semaphor) n(e) h(is) h -(incr) n(emented.) p 90 rotate dyy eop -%%Page: 3 3 -3 2 bop Fg 3306 249 a(3) 204 548 y(If) 27 b(a) h(thr) n(ead) e(cal) r -(ls) p Fd 27 w(try) n(_wait) n(\(\)) p Fg(,) h(then) g(the) f(thr) n -(ead) g(won't) h(block) h(if) f(the) g(semaphor) n(e's) 63 -661 y(value) c(is) g(0,) g(r) n(eturning) p Fd 21 w(false) p -Fg 21 w(instead.) 204 777 y(Ther) n(e) f(is) g(no) h(way) f(of) h -(query) n(ing) g(the) f(value) h(of) g(the) f(semaphor) n(e) n(.) p -Fh 63 1095 a(3) 119 b(Thread) 29 b(object) p Fg 63 1313 -a(A) 23 b(thr) n(ead) g(is) h(r) n(epr) n(ese) n(nted) e(by) i(an) p -Fd 24 w(omni) n(_thr) n(ead) p Fg 23 w(object.) 30 b(Ther) n(e) 23 -b(ar) n(e) h(br) n(oadly) g(two) e(dif) n(fer) n(-) 63 -1426 y(ent) f(ways) i(in) g(which) g(it) g(can) g(be) g(used) n(.) 204 -1542 y(The) 28 b(\002rst) g(way) h(is) h(simply) f(to) f(cr) n(eate) h -(an) p Fd 30 w(omn) n(i_thr) n(ead) p Fg 28 w(object,) h(giving) g(a) f -(particula) r(r) 63 1655 y(function) c(which) h(the) e(thr) n(ead) h -(should) f(execute) n(.) 36 b(This) 25 b(is) g(like) g(the) g(POSIX) f -(\(or) i(any) f(other) n(\)) h(C) 63 1768 y(language) c(interface.) 204 -1884 y(The) k(second) f(method) h(of) h(use) e(is) i(to) f(cr) n(eate) h -(a) g(new) g(class) g(which) g(inherits) f(fr) n(om) p -Fd 28 w(omn) n(i_) 63 1997 y(thr) n(ead) p Fg(.) 50 b(In) 31 -b(this) f(case) g(the) g(thr) n(ead) g(will) i(execute) d(the) p -Fd 29 w(run\(\)) p Fg 29 w(member) h(function) h(of) f(the) 63 -2109 y(new) 22 b(class.) 29 b(One) 23 b(advantage) g(of) g(this) g -(scheme) f(is) h(that) g(thr) n(ead-speci\002c) g(data) g(can) h(be) f -(imple-) 63 2222 y(mented) e(simply) h(by) h(having) g(data) g(members) -f(of) h(the) f(new) g(class.) 204 2339 y(When) f(constr) o(ucted) g(a) i -(thr) n(ead) f(is) g(in) h(the) e("new") h(state) f(and) h(has) g(not) g -(actuall) r(y) g(starte) n(d.) 28 b(A) 63 2451 y(call) j(to) p -Fd 29 w(sta) n(rt\(\)) p Fg 28 w(causes) e(the) g(thr) n(ead) g(to) g -(begin) g(executing.) 47 b(A) 29 b(static) h(member) f(function) p -Fd 63 2564 a(cre) n(ate\() n(\)) p Fg 32 w(is) j(pr) n(ovided) f(to) g -(constr) o(uct) g(and) g(start) g(a) i(thr) n(ead) e(in) h(a) g(single) -g(call.) 57 b(A) 31 b(thr) n(ead) 63 2677 y(exits) 21 -b(by) i(call) r(ing) p Fd 22 w(exit\() n(\)) p Fg 22 -w(or) g(by) f(r) n(eturning) g(fr) n(om) h(the) f(thr) n(ead) g -(function.) 204 2793 y(Thr) n(eads) 27 b(can) j(be) e(either) g -(detached) f(or) h(undetached) n(.) 46 b(Detached) 28 -b(thr) n(eads) g(ar) n(e) h(thr) n(eads) 63 2906 y(for) h(which) i(all) -g(state) e(will) i(be) f(lost) f(upon) g(exit.) 52 b(Other) 30 -b(thr) n(eads) g(cannot) h(dete) n(rmine) g(when) 63 -3019 y(a) e(detached) f(thr) n(ead) h(will) h(disappear) -7 -b(,) 31 b(and) e(ther) n(efor) n(e) f(should) g(not) h(attempt) f(to) g -(access) h(the) 63 3132 y(thr) n(ead) 23 b(object) g(unless) f(some) h -(explicit) h(synchr) n(onisation) f(with) g(the) g(detached) f(thr) n -(ead) h(guar) n(-) 63 3245 y(antees) e(that) h(it) h(still) g(exists.) -204 3361 y(Undet) n(ached) 33 b(thr) n(eads) f(ar) n(e) i(thr) n(eads) e -(for) h(which) g(storage) f(is) h(not) f(r) n(eclai) r(med) g(until) i -(an-) 63 3474 y(othe) n(r) g(thr) n(ead) g(waits) g(for) g(its) g -(termination) g(by) g(call) r(ing) p Fd 34 w(joi) n(n\(\)) p -Fg(.) 61 b(An) 34 b(exit) g(value) h(can) g(be) 63 3587 -y(passe) n(d) 23 b(fr) n(om) g(an) g(undet) n(ached) g(thr) n(ead) f -(to) g(the) g(thr) n(ead) g(which) h(joins) g(it.) 204 -3703 y(Detached) 31 b(/) h(undetached) e(thr) n(eads) h(ar) n(e) i -(distinguish) n(ed) f(on) f(cr) n(eation) h(by) g(the) f(type) g(of) 63 -3816 y(function) 24 b(they) e(execute.) 30 b(Undetached) 22 -b(thr) n(eads) h(execute) g(a) h(function) g(which) g(has) g(a) p -Fd 25 w(voi) n(d*) p Fg 63 3929 a(r) n(eturn) c(typ) n(e,) h(wher) n -(eas) f(detached) f(thr) n(eads) h(execute) f(a) j(function) f(which) g -(has) g(a) p Fd 21 w(void) p Fg 19 w(r) n(eturn) 63 4042 -y(typ) n(e.) 52 b(Unfortunate) n(ly) 31 b(C++) g(member) g(functions) f -(ar) n(e) h(not) f(allowed) g(to) g(be) h(distingu) n(ished) 63 -4155 y(simply) 26 b(by) h(their) f(r) n(eturn) g(type) n(.) 40 -b(Thus) 26 b(in) h(the) f(case) h(of) g(a) g(derived) f(class) h(of) p -Fd 26 w(omni_) n(thre) n(ad) p Fg 63 4268 a(which) 20 -b(needs) e(an) j(undet) n(ached) f(thr) n(ead,) g(the) f(member) h -(function) g(execute) n(d) g(by) g(the) f(thr) n(ead) g(is) 63 -4380 y(called) p Fd 19 w(run_u) n(ndet) n(ache) n(d\(\)) p -Fg 18 w(rather) f(than) p Fd 19 w(run\() n(\)) p Fg(,) h(and) g(it) g -(is) g(started) e(by) i(calli) r(ng) p Fd 18 w(star) n(t_) 63 -4493 y(und) n(etac) n(hed\(\)) p Fg 21 w(instead) j(of) p -Fd 22 w(start) n(\(\)) p Fg(.) 204 4610 y(The) i(abstraction) i(curr) n -(ently) e(suppo) n(rts) h(thr) n(ee) f(priorities) g(of) h(thr) n(ead,) -g(but) g(no) g(guarantee) 63 4722 y(is) 33 b(made) g(of) h(how) f(this) -g(will) h(af) n(f) r(ect) f(underlying) f(thr) n(ead) h(scheduling.) 59 -b(The) 33 b(thr) n(ee) f(priori-) 63 4835 y(ties) 18 -b(ar) n(e) p Fd 20 w(PRIO) n(RITY) n(_LOW) p Fg(,) p -Fd 18 w(PRIO) n(RITY) n(_NOR) n(MAL) p Fg 19 w(and) p -Fd 19 w(PRIO) n(RITY) n(_HIG) n(H) p Fg(.) h(By) g(default) g(all) 63 -4948 y(thr) n(eads) i(r) o(un) i(at) p Fd 23 w(PRIO) n(RITY) n(_NORM) n -(AL) p Fg(.) f(A) g(dif) n(fer) n(ent) h(priority) f(can) i(be) e -(speci\002ed) g(on) g(thr) n(ead) 63 5061 y(cr) n(eation,) h(or) f -(while) h(the) f(thr) n(ead) g(is) h(r) o(unning) g(using) p -Fd 22 w(set_) n(prio) n(rity\() n(\).) p Fg 28 w(A) g(thr) n(ead's) f -(cur) n(-) 63 5174 y(r) n(ent) g(priority) g(is) g(r) n(eturned) f(by) p -Fd 23 w(pri) n(ority) n(\(\)) p Fg(.) 204 5290 y(Other) d(functions) g -(pr) n(ovided) g(ar) n(e) p Fd 19 w(sel) n(f\(\)) p Fg -18 w(which) h(r) n(eturns) e(the) h(calli) r(ng) g(thr) n(ead's) p -Fd 18 w(omn) n(i_) 63 5403 y(thr) n(ead) p Fg 36 w(object,) p -Fd 40 w(yie) n(ld\(\)) p Fg 35 w(which) 38 b(r) n(eques) n(ts) e(that) h -(other) e(thr) n(eads) h(be) h(allowed) g(to) f(r) o(un,) p -90 rotate dyy eop -%%Page: 4 4 -4 3 bop Fg 221 249 a(4) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23 -b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fd 221 548 a(id\(\)) p -Fg 27 w(which) 29 b(r) n(eturns) e(an) i(intege) n(r) g(id) f(for) h -(the) e(thr) n(ead) h(for) g(use) g(in) h(debug) n(ging,) p -Fd 29 w(state) n(\(\)) p Fg(,) p Fd 221 661 a(slee) n(p\(\)) p -Fg 22 w(and) p Fd 22 w(get_t) n(ime\() n(\)) p Fg(.) p -Fh 221 953 a(4) 119 b(Per) n(-threa) n(d) 30 b(data) p -Fg 221 1164 a(omnithr) n(ead) 22 b(suppo) n(rts) g(per) n(-thr) n(ead) f -(data,) h(via) i(member) e(functions) f(of) i(the) p -Fd 21 w(omni) n(_thr) n(ead) p Fg 221 1277 a(object.) 362 -1390 y(First,) d(you) g(must) h(allocate) h(a) f(key) f(for) g(with) h -(the) p Fd 20 w(omni) n(_thre) n(ad::) n(allo) n(cate_) n(key\() n(\)) p -Fg 221 1502 a(function.) 28 b(Then,) 21 b(any) h(object) g(whose) f -(class) h(is) g(derived) f(fr) n(om) p Fd 23 w(omni) n(_thr) n(ead::) n -(valu) n(e_t) p Fg 221 1615 a(can) 27 b(be) f(stor) n(e) n(d) g(using) f -(the) p Fd 26 w(set) n(_val) n(ue\(\)) p Fg 25 w(function.) 38 -b(V) -8 b(alues) 25 b(ar) n(e) h(r) n(etrieved) f(or) h(r) n(emoved) 221 -1728 y(with) p Fd 23 w(get) n(_valu) n(e\(\)) p Fg 21 -w(and) p Fd 23 w(remo) n(ve_v) n(alue\() n(\)) p Fg 22 -w(r) n(espectively) -10 b(.) 362 1841 y(When) 23 b(the) g(thr) n(ead) g -(exits,) g(all) i(per) n(-thr) n(ead) e(data) h(is) g(delet) n(ed) f -(\(hence) h(the) e(base) i(class) g(with) 221 1954 y(virtual) g(dest) n -(r) o(uctor\).) 362 2067 y(Note) 17 b(that) i(the) f(per) n(-thr) n -(ead) f(data) i(functions) f(ar) n(e) p Fb 19 w(not) p -Fg 18 w(thr) n(ead) g(safe,) i(so) d(although) i(you) e(can) 221 -2180 y(access) 29 b(one) e(thr) n(ead's) h(storage) f(fr) n(om) i -(another) f(thr) n(ead,) h(ther) n(e) e(is) i(no) f(concurr) n(ency) g -(contr) n(ol.) 221 2293 y(Unless) j(you) g(r) n(eall) r(y) h(know) f -(what) h(you) f(ar) n(e) i(doing,) g(it) g(is) f(best) f(to) h(only) g -(access) g(per) n(-thr) n(ead) 221 2406 y(data) 23 b(fr) n(om) g(the) f -(thr) n(ead) g(it) h(is) g(attached) f(to.) p Fh 221 -2698 a(5) 119 b(Using) 31 b(OMNI) d(threads) h(in) h(your) g(program) p -Fg 221 2909 a(Obvi) r(ously) 16 b(you) h(need) g(to) g(include) h(the) p -Fd 16 w(omnit) n(hrea) n(d.h) p Fg 17 w(header) e(\002le) i(in) g(your) -f(sour) n(ce) g(code,) 221 3021 y(and) 25 b(link) g(in) h(the) e -(omnithr) n(ead) g(libra) r(ry) g(with) h(your) f(execut) n(abl) r(e.) -34 b(Because) 23 b(ther) n(e) h(is) h(a) g(single) p -Fd 221 3134 a(omni) n(threa) n(d.h) p Fg 30 w(for) 32 -b(all) h(platforms,) h(certain) e(pr) n(epr) n(oces) n(sor) f -(de\002nes) f(must) h(be) g(given) h(as) 221 3247 y(compiler) 25 -b(options) n(.) 33 b(The) 23 b(easiest) g(way) h(to) g(do) f(this) h -(is) g(to) g(stud) n(y) g(the) g(make\002les) f(given) h(in) h(the) 221 -3360 y(examples) i(pr) n(ovided) g(with) g(this) g(distribution.) 42 -b(If) 27 b(you) g(ar) n(e) g(to) g(include) h(OMNI) f(thr) n(eads) g -(in) 221 3473 y(your) 18 b(own) g(development) g(envir) n(onment,) h -(thes) n(e) g(ar) n(e) g(the) f(necessary) g(pr) n(epr) n(oce) n(ssor) g -(de\002nes) n(:) p 362 3567 3287 4 v 360 3680 4 113 v -412 3646 a(Platform) p 1312 3680 V 599 w(Pr) n(epr) n(ocess) n(or) 23 -b(De\002nes) p 3648 3680 V 362 3683 3287 4 v 362 3700 -V 360 3813 4 113 v 412 3779 a(Sun) f(Solaris) h(2.x) p -1312 3813 V Fd 365 w(-D__) n(suno) n(s__) 54 b(-D_) n(_spa) n(rc__) f -(-D__) n(OSVER) n(SION) n(__=5) p 3648 3813 V 360 3926 -V 1312 3926 V 1363 3892 a(-DSV) n(R4) h(-DUs) n(ePth) n(read) f(-D_R) n -(EENT) n(RANT) p 3648 3926 V 362 3929 3287 4 v 360 4042 -4 113 v Fg 412 4008 a(x86) 24 b(Linux) e(2.0) p 1312 -4042 V Fd 418 w(-D__) n(linu) n(x__) 54 b(-D_) n(_i86) n(__) g(-D__) n -(OSVE) n(RSION) n(__=2) p 3648 4042 V 360 4155 V Fg 412 -4121 a(with) 23 b(linuxthr) n(eads) f(0.5) p 1312 4155 -V Fd 100 w(-D_R) n(EENT) n(RANT) p 3648 4155 V 362 4158 -3287 4 v 360 4271 4 113 v Fg 412 4237 a(Digital) i(Unix) f(3.2) p -1312 4271 V Fd 320 w(-D__) n(osf1) n(__) 54 b(-D__) n(alph) n(a__) g -(-D_) n(_OSV) n(ERSIO) n(N__=) n(3) p 3648 4271 V 360 -4384 V 1312 4384 V 1363 4350 a(-D_R) n(EENT) n(RANT) p -3648 4384 V 362 4387 3287 4 v 360 4500 4 113 v Fg 412 -4466 a(W) -5 b(indows) 22 b(NT) p 1312 4500 V Fd 411 -w(-D__) n(NT__) 53 b(-MD) p 3648 4500 V 362 4503 3287 -4 v Fh 221 4740 a(6) 119 b(Threaded) 29 b(I/O) g(shutdown) h(for) g -(Unix) p Fg 221 4951 a(or) -7 b(,) 20 b(how) e(one) g(thr) n(ead) h -(shou) n(ld) h(tell) f(another) f(thr) n(ead) g(to) h(shut) f(down) g -(when) g(it) h(might) g(be) g(doing) 221 5064 y(a) k(blocking) g(cal) r -(l) g(on) f(a) h(socket) n(.) p Fb 362 5177 a(If) h(you) e(are) i -(using) e(omniOR) n(B,) h(you) e(don') n(t) i(need) g(to) g(worry) f -(about) g(all) i(this,) f(since) h(om-) 221 5290 y(niORB) i(does) h(it) -h(for) f(you) n(.) p Fg 41 w(This) g(section) f(is) h(only) g(r) n -(elevant) g(if) h(you) e(ar) n(e) h(using) f(omnithr) n(ead) 221 -5403 y(in) d(your) f(own) g(socket) n(-based) h(pr) n(ogramming.) k(It) -22 b(is) h(also) g(serious) n(ly) g(out) f(of) h(date.) p -90 rotate dyy eop -%%Page: 5 5 -5 4 bop Fe 63 249 a(6.1) 91 b(r) n(ead\(\)) p Fg 2800 -w(5) 204 548 y(Unfortunate) n(ly) 35 b(ther) n(e) e(doe) n(sn't) h -(seem) f(to) h(be) g(a) h(standar) n(d) e(way) i(of) f(doing) f(this) h -(which) 63 661 y(works) 19 b(acr) n(oss) i(all) i(Unix) e(syst) n(ems.) -27 b(I) 21 b(have) g(investigated) f(the) h(behaviour) g(of) g(Solaris) -h(2.5) g(and) 63 774 y(Digital) k(Unix) g(3.2.) 36 b(On) 26 -b(Digital) h(Unix) e(everyth) n(ing) h(is) f(\002ne,) g(as) h(the) e -(obvious) h(method) f(using) 63 887 y(shutd) n(own\(\)) 32 -b(seems) f(to) h(work) f(OK.) h(Unfortunately) f(on) h(Solaris) h(shut) -n(down) f(can) h(only) f(be) 63 1000 y(used) 25 b(on) h(a) h(connected) -e(socke) n(t,) i(so) f(we) g(need) f(devious) h(means) g(to) g(get) f -(ar) n(ound) h(this) g(lim) r(ita-) 63 1112 y(tion.) h(The) 22 -b(details) g(ar) n(e) h(summarised) g(below:) p Fc 63 -1429 a(6.1) 99 b(read\(\)) p Fg 63 1627 a(Thr) n(ead) 28 -b(A) h(is) g(in) h(a) g(loop,) g(doing) p Fd 28 w(rea) n(d\(soc) n(k\)) -p Fg(,) g(pr) n(ocess) n(ing) f(the) g(data,) h(then) f(going) f(back) -63 1739 y(into) 22 b(the) g(r) n(ead.) 204 1862 y(Thr) n(ead) 30 -b(B) h(comes) f(along) h(and) g(wants) f(to) g(shut) g(it) h(down) f -(\227) h(it) g(can't) g(cancel) h(thr) n(ead) f(A) 63 -1975 y(since) 21 b(\(i\)) h(working) e(out) g(how) g(to) h(clean) h(up) -e(accor) n(ding) i(to) e(wher) n(e) g(A) h(is) g(in) h(its) f(loop) f -(is) h(a) h(night-) 63 2088 y(mar) n(e,) h(and) f(\(ii\)) i(this) f -(isn't) f(ava) r(ilabl) r(e) g(in) h(omnithr) n(ead) f(anyway) -10 -b(.) 204 2211 y(On) 23 b(Solaris) g(2.5) g(and) g(Digital) h(Unix) f -(3.2) g(the) f(following) h(strate) n(gy) f(works:) 204 -2334 y(Thr) n(ead) g(B) g(does) p Fd 21 w(shut) n(down\() n(sock) n -(,2\)) p Fg(.) 204 2457 y(At) g(this) g(point) h(thr) n(ead) f(A) g(is) -h(either) f(blocked) g(inside) p Fd 23 w(rea) n(d\(so) n(ck\)) p -Fg(,) g(or) g(is) h(elsewhe) n(r) n(e) g(in) 63 2570 -y(the) 18 b(loop.) 26 b(If) 18 b(the) g(former) h(then) f(r) n(ead) h -(will) h(r) n(eturn) e(0,) i(indicating) f(that) g(the) f(socke) n(t) h -(is) g(closed.) 26 b(If) 63 2683 y(the) 21 b(latter) h(then) f -(eventually) h(thr) n(ead) g(A) g(will) i(call) p Fd -24 w(rea) n(d\(so) n(ck\)) p Fg 21 w(and) f(then) e(this) h(will) h(r) n -(eturn) 63 2796 y(0.) 28 b(Thr) n(ead) 22 b(A) h(should) p -Fd 21 w(clos) n(e\(soc) n(k\)) p Fg(,) f(do) g(any) g(other) g(tidying) -f(up,) h(and) h(exit.) 204 2919 y(If) 34 b(ther) n(e) g(is) h(another) f -(point) g(in) h(the) e(loop) i(that) f(thr) n(ead) g(A) h(can) g(block) -g(then) f(obviously) 63 3032 y(thr) n(ead) 19 b(B) h(needs) f(to) h(be) -g(awar) n(e) h(of) f(this) g(and) g(be) h(able) g(to) e(wake) h(it) h -(up) f(in) g(the) g(appr) n(opriate) g(way) 63 3145 y(fr) n(om) j(that) -f(point.) p Fc 63 3462 a(6.2) 99 b(accept\(\)) p Fg 63 -3659 a(Again) 25 b(thr) n(ead) g(A) h(is) f(in) h(a) g(loop,) g(this) f -(time) h(doing) e(an) i(acc) r(ept) e(on) h(listenSock,) g(dealing) h -(with) 63 3772 y(a) d(new) f(connection) g(and) h(going) e(back) j -(into) e(accept.) 28 b(Thr) n(ead) 22 b(B) g(wants) h(to) f(cancel) h -(it.) 204 3895 y(On) g(Digital) h(Unix) f(3.2) g(the) f(strateg) n(y) g -(is) h(identical) h(to) e(that) g(for) h(r) n(ead:) 204 -4018 y(Thr) n(ead) 39 b(B) g(does) p Fd 38 w(shut) n(down) n(\(list) n -(enSo) n(ck,2) n(\)) p Fg(.) 79 b(Wher) n(ever) 38 b(thr) n(ead) h(A) h -(is) f(in) h(the) 63 4131 y(loop,) i(eventually) c(it) h(will) h(r) n -(eturn) p Fd 38 w(ECONN) n(ABOR) n(TED) p Fg 38 w(fr) n(om) f(the) f -(accept) h(call) r(.) 76 b(It) 39 b(shou) n(ld) p Fd -63 4244 a(clo) n(se\(l) n(isten) n(Sock) n(\)) p Fg(,) 22 -b(tidy) g(up) g(as) h(necessary) e(and) i(exit.) 204 -4367 y(On) 30 b(Solaris) f(2.5) i(thr) n(ead) e(B) g(can't) h(do) p -Fd 29 w(shu) n(tdow) n(n\(lis) n(tenS) n(ock,2) n(\)) p -Fg 29 w(\227) g(this) f(r) n(eturns) p Fd 63 4480 a(ENO) n(TCON) n(N) p -Fg(.) 22 b(Instead) f(the) h(following) h(strateg) n(y) g(can) g(be) g -(used) n(:) 204 4603 y(First) 35 b(thr) n(ead) h(B) g(set) n(s) g(some) -f(sort) g(of) h("shutdo) n(wn) g(\003ag") g(associated) g(with) g -(listenSock.) 63 4716 y(Then) 31 b(it) h(does) p Fd 30 -w(gets) n(ocka) n(ddr\(l) n(iste) n(nSock) n(\)) p Fg -32 w(to) f(\002nd) g(out) g(which) i(port) e(listenSock) f(is) 63 -4828 y(on) 18 b(\(or) h(knows) e(alr) n(eady\),) j(sets) d(up) h(a) h -(socket) e(dummySock,) i(doe) n(s) p Fd 19 w(con) n(nect) n(\(dumm) n -(ySoc) n(k,) 63 4941 y(thi) n(s) 54 b(host,) f(por) n(t\)) p -Fg 22 w(and) 23 b(\002nally) g(does) p Fd 21 w(clos) n(e\(dum) n(mySo) n -(ck\)) p Fg(.) 204 5064 y(Wher) n(ever) 16 b(thr) n(ead) h(A) g(is) g -(in) h(the) e(loop,) h(eventually) g(it) h(will) g(call) p -Fd 19 w(acce) n(pt\(li) n(sten) n(Sock) n(\)) p Fg(.) 63 -5177 y(This) 35 b(will) j(r) n(eturn) d(successfully) g(with) h(a) h -(new) e(socket,) j(say) e(connSock.) 67 b(Thr) n(ead) 36 -b(A) f(then) 63 5290 y(checks) 20 b(to) h(see) f(if) i(the) f("shutd) n -(own) g(\003ag") h(is) f(set.) 26 b(If) c(not,) e(then) h(it's) g(a) h -(normal) g(connection.) 27 b(If) 21 b(it) 63 5403 y(is) h(set,) g(then) -f(thr) n(ead) h(A) h(closes) f(listenSock) f(and) i(connSock,) e -(tidies) h(up) g(and) h(exits.) p 90 rotate dyy eop -%%Page: 6 6 -6 5 bop Fg 221 249 a(6) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23 -b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fc 221 548 a(6.3) 99 -b(write\(\)) p Fg 221 768 a(Thr) n(ead) 19 b(A) f(may) h(be) g(blocked) -f(in) i(write,) f(or) f(about) h(to) f(go) g(in) h(to) g(a) g(poten) n -(tiall) r(y-blocking) g(write.) 221 881 y(Thr) n(ead) j(B) h(wants) f -(to) g(shut) f(it) i(down.) 362 1016 y(On) g(Solaris) g(2.5:) 362 -1150 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n(\(soc) n -(k,2\)) p Fg -2 w(.) 362 1285 y(If) c(thr) n(ead) f(A) h(is) g(alr) n -(eady) g(in) p Fd 20 w(wri) n(te\(s) n(ock\)) p Fg 17 -w(then) f(it) h(will) i(r) n(eturn) d(with) p Fd 18 w(ENXIO) p -Fg -2 w(.) h(If) g(thr) n(ead) 221 1398 y(A) k(calls) h(write) e(after) -g(thr) n(ead) g(B) h(calls) h(shut) n(down) e(this) g(will) i(r) n -(eturn) p Fd 22 w(EIO) p Fg(.) 362 1532 y(On) f(Digital) h(Unix) f -(3.2:) 362 1666 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 -w(shu) n(tdown) n(\(soc) n(k,2\)) p Fg -2 w(.) 362 1801 -y(If) h(thr) n(ead) f(A) g(is) h(alr) n(eady) g(in) p -Fd 24 w(writ) n(e\(so) n(ck\)) p Fg 23 w(then) e(it) i(will) h(r) n -(eturn) e(the) f(number) i(of) f(bytes) 221 1914 y(written) 31 -b(befor) n(e) h(it) g(became) g(blocked.) 55 b(A) 32 -b(subseq) n(uent) f(cal) r(l) h(to) f(write) h(will) h(then) e(gene) n -(rate) p Fd 221 2027 a(SIGP) n(IPE) p Fg 22 w(\(or) p -Fd 22 w(EPIP) n(E) p Fg 23 w(will) 24 b(be) e(r) n(eturned) f(if) p -Fd 24 w(SIG) n(PIPE) p Fg 21 w(is) i(ignor) n(ed) e(by) i(the) f(thr) n -(ead\).) p Fc 221 2413 a(6.4) 99 b(connect\(\)) p Fg -221 2634 a(Thr) n(ead) 30 b(A) f(may) h(be) g(blocked) f(in) i -(connect,) g(or) e(about) h(to) f(go) g(in) i(to) e(a) h(poten) n -(tiall) r(y-blocking) 221 2747 y(connect.) d(Thr) n(ead) c(B) f(wants) g -(to) g(shut) g(it) g(down.) 362 2881 y(On) h(Digital) h(Unix) f(3.2:) -362 3016 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n -(\(soc) n(k,2\)) p Fg -2 w(.) 362 3150 y(If) j(thr) n(ead) f(A) g(is) h -(alr) n(eady) g(in) p Fd 26 w(conn) n(ect\() n(sock) n(\)) p -Fg 26 w(then) e(it) i(will) h(r) n(eturn) e(a) h(successful) f(con-) 221 -3263 y(nection.) 54 b(Subsequ) n(ent) 31 b(r) n(eading) g(or) g -(writing) g(will) i(show) d(that) i(the) e(socket) g(has) h(been) g -(shut) 221 3376 y(down) 22 b(\(i.e.) 28 b(r) n(ead) 23 -b(r) n(eturns) e(0,) i(write) f(generate) n(s) p Fd 23 -w(SIG) n(PIPE) p Fg 21 w(or) g(r) n(eturns) p Fd 22 w(EPI) n(PE) p -Fg(\).) g(If) h(thr) n(ead) f(A) 221 3489 y(call) r(s) g(connect) g -(after) h(thr) n(ead) f(B) g(call) r(s) g(shutdo) n(wn) h(this) f(will) -i(r) n(eturn) p Fd 22 w(EIN) n(VAL) p Fg(.) 362 3623 -y(On) f(Solaris) g(2.5:) 362 3758 y(Ther) n(e) 35 b(is) h(no) f(way) g -(to) g(wake) g(up) g(a) h(thr) n(ead) f(which) h(is) g(blocked) f(in) h -(connect.) 66 b(Inst) n(ead) 221 3871 y(Solaris) 33 b(for) n(ces) g(us) -f(thr) n(ough) g(a) i(ridiculous) f(pr) n(oced) n(ur) n(e) g(whichever) -g(way) g(we) f(try) g(it.) 59 b(One) 221 3984 y(way) 23 -b(is) f(this:) 362 4118 y(First) d(thr) n(ead) h(A) g(cr) n(eates) f(a) -h(pipe) g(in) g(addition) g(to) f(the) g(socket) n(.) 27 -b(Instead) 19 b(of) h(shut) n(ting) g(down) 221 4231 -y(the) i(socket) n(,) h(thr) n(ead) f(B) g(simply) h(writes) e(a) i -(byte) f(to) g(the) g(pipe.) 362 4365 y(Thr) n(ead) 17 -b(A) g(meanwhile) h(set) n(s) f(the) g(socke) n(t) g(to) g -(non-blocking) g(mode) f(using) p Fd 17 w(fcn) n(tl\(s) n(ock,) 221 -4478 y(F_SE) n(TFL,) 53 b(O_NO) n(NBLO) n(CK\)) p Fg(.) 26 -b(Then) h(it) g(cal) r(ls) g(connect) g(on) g(the) f(socket) g(\227) h -(this) g(will) i(r) n(eturn) p Fd 221 4591 a(EINP) n(ROGRE) n(SS) p -Fg(.) k(Then) h(it) h(must) e(cal) r(l) p Fd 35 w(sel) n(ect\() n(\)) p -Fg(,) k(waiting) e(for) f(either) g(sock) g(to) f(become) 221 -4704 y(writable) 39 b(or) f(for) h(the) e(pipe) h(to) g(become) g(r) n -(eadable.) 75 b(If) 39 b(select) e(r) n(eturns) g(that) i(just) e(sock) -h(is) 221 4817 y(writable) 30 b(then) f(the) g(connection) g(has) h -(succeede) n(d.) 49 b(It) 29 b(then) g(need) n(s) h(to) f(set) f(the) h -(socket) f(back) 221 4930 y(to) i(blocking) h(mode) f(using) p -Fd 30 w(fcnt) n(l\(so) n(ck,) 54 b(F_S) n(ETFL) n(,) h(0\)) p -Fg(.) c(If) 31 b(instead) e(select) h(r) n(eturns) 221 -5043 y(that) 23 b(the) e(pipe) h(is) h(r) n(eadable,) g(thr) n(ead) f -(A) h(closes) e(the) h(socket) n(,) h(tidies) f(up) g(and) h(exits.) 362 -5177 y(An) g(alternative) h(method) e(is) i(similar) h(but) e(to) g -(use) f(polling) i(instead) e(of) i(the) e(pipe.) 29 -b(Thr) n(ead) 221 5290 y(B) 24 b(justs) e(sets) g(a) j(\003ag) f(and) g -(thr) n(ead) f(A) h(calls) h(select) e(with) g(a) i(timeout,) e(period) -n(ica) r(lly) h(waking) f(up) 221 5403 y(to) f(see) g(if) h(the) f -(\003ag) h(has) f(been) g(set.) p 90 rotate dyy eop -%%Page: 7 7 -7 6 bop Fe 63 249 a(REF) n(ERENCES) p Fg 2660 w(7) p -Fh 63 548 a(Refere) n(nces) p Fg 63 759 a([POSIX94]) p -Fa 46 w(Portable) 29 b(Operat) r(ing) f(System) g(Interface) h -(\(POSIX\)) e(Thr) n(ea) r(ds) h(Extension) p Fg(,) h(P1003) r(.1c) 245 -872 y(Draft) 23 b(10,) g(IEEE,) e(Septe) n(mber) i(1994) r(.) 63 -1059 y([Birr) n(ell89]) p Fa 47 w(An) 28 b(Intr) n(od) r(uction) g(to) h -(Pr) n(ogr) r(amming) g(with) g(Thr) n(ead) r(s) p Fg(,) h(Rese) n(ar) n -(ch) g(Repo) n(rt) e(35,) j(DEC) 245 1172 y(Syst) n(ems) 22 -b(Resear) n(ch) g(Center) -7 b(,) 22 b(Palo) h(Alto,) f(CA,) h(January) -g(1989) r(.) p 90 rotate dyy eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF -- cgit From d692a41f98e7b888c745efbb9fcbbb0400f39025 Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Wed, 24 Nov 2010 17:29:11 -0800 Subject: Major Makefile.am housecleaning. Passes distcheck. Move all occurrences of swig_built_sources out of Makefile.am's. Move all SWIG related use of BUILT_SOURCES out of Makefile.am's. Clean up 'if PYTHON' conditionalization in gr-* Still left to do: fix Makefile.swig CLEANFILES and no_dist_files such that they remove exactly the generated files. --- docs/doxygen/other/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/Makefile.am b/docs/doxygen/other/Makefile.am index eb5f170af..82ee0f945 100644 --- a/docs/doxygen/other/Makefile.am +++ b/docs/doxygen/other/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ doxypy.py \ group_defs.dox \ shared_ptr_docstub.h \ -- cgit From da19886cfec78db4a4db0f8e2a34afe796da9057 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 8 Oct 2011 15:29:50 -0400 Subject: gcell: removed gcell and gr-gcell --- docs/doxygen/other/group_defs.dox | 8 -------- 1 file changed, 8 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 6f2e1ac7f..52f67c06e 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -66,12 +66,4 @@ /*! \defgroup usrp USRP */ /*! \defgroup usrp2 USRP2 */ -/*! - * \defgroup gcell gcell: Cell Broadband Engine SPE Scheduler & RPC Mechanism - * - * For additional information please see the - * gcell wiki page - * and gcell-sdrf-2008.pdf. - */ - /*! \defgroup hardware Misc Hardware Control */ -- cgit From 1ccc199c649c4d391eb544de7d29e292023125a3 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 16:40:53 -0400 Subject: digital: adding Doxygen group digital --- docs/doxygen/other/group_defs.dox | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 52f67c06e..e063957ba 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -27,6 +27,7 @@ /*! \defgroup misc_blk Miscellaneous Blocks */ /*! \defgroup slicedice_blk Slicing and Dicing Streams */ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ +/*! \defgroup digital Digital Modulation Blocks */ /*! * \defgroup base_blk Base classes for GR Blocks -- cgit From 34c8a8e591ec0dabe6e9bab0d65d3eae27ebb2db Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 16:55:33 -0400 Subject: docs: This adds documentation to gr-digital in the form of a README.digital and a digital modulation page for the Doxygen manual. The manual's main page has been updated to link to the new digital modulation page. --- docs/doxygen/other/main_page.dox | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 43fcbf67a..4c5aef7a4 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -9,4 +9,6 @@ provide unified documentation for the C++ parts of the system and the parts written in Python (mostly hierarchical blocks). Until this gets worked out, please bear with us, or better yet, solve it for us! +\li \ref page_digital + */ -- cgit From 2656ad175c70322902b960db5ac649c7bbfa0572 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 17:10:12 -0400 Subject: docs: adding README.vocoder and a Doxygen page for the vocoder block. --- docs/doxygen/other/main_page.dox | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 4c5aef7a4..0d2ce5d64 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -9,6 +9,8 @@ provide unified documentation for the C++ parts of the system and the parts written in Python (mostly hierarchical blocks). Until this gets worked out, please bear with us, or better yet, solve it for us! +More details on packages in GNU Radio: \li \ref page_digital +\li \ref page_vocoder */ -- cgit From a8824153f56cfd1d442422ede0f9cd2f4ee2231e Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 18:01:32 -0400 Subject: doc: adding qtgui Doxygen documentation page and a README file. --- docs/doxygen/other/group_defs.dox | 1 + docs/doxygen/other/main_page.dox | 1 + 2 files changed, 2 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index e063957ba..27b2109dc 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -28,6 +28,7 @@ /*! \defgroup slicedice_blk Slicing and Dicing Streams */ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ /*! \defgroup digital Digital Modulation Blocks */ +/*! \defgroup qtgui_blk QT Graphical Interfaces */ /*! * \defgroup base_blk Base classes for GR Blocks diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 0d2ce5d64..0abf934d5 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -12,5 +12,6 @@ worked out, please bear with us, or better yet, solve it for us! More details on packages in GNU Radio: \li \ref page_digital \li \ref page_vocoder +\li \ref page_qtgui */ -- cgit From 7ba45cf3452123a4c08a4aa535da76b793d2eaf2 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 19:23:33 -0400 Subject: docs: adding uhd Doxygen documentation page and README file. --- docs/doxygen/other/group_defs.dox | 1 + docs/doxygen/other/main_page.dox | 1 + 2 files changed, 2 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 27b2109dc..4dfc842fe 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -29,6 +29,7 @@ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ /*! \defgroup digital Digital Modulation Blocks */ /*! \defgroup qtgui_blk QT Graphical Interfaces */ +/*! \defgroup uhd_blk UHD Interface */ /*! * \defgroup base_blk Base classes for GR Blocks diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 0abf934d5..1d9c0f972 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -13,5 +13,6 @@ More details on packages in GNU Radio: \li \ref page_digital \li \ref page_vocoder \li \ref page_qtgui +\li \ref page_uhd */ -- cgit From 79b68aa7f9f67a3ce2f48582bc062e8c5cba2413 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 9 Oct 2011 21:58:40 -0400 Subject: docs: adding doc directory, Doxygen page, and README for audio package. --- docs/doxygen/other/group_defs.dox | 1 + docs/doxygen/other/main_page.dox | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 4dfc842fe..646df6855 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -30,6 +30,7 @@ /*! \defgroup digital Digital Modulation Blocks */ /*! \defgroup qtgui_blk QT Graphical Interfaces */ /*! \defgroup uhd_blk UHD Interface */ +/*! \defgroup audio_blk Audio Interface */ /*! * \defgroup base_blk Base classes for GR Blocks diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 1d9c0f972..f8d0dcf73 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -10,9 +10,10 @@ parts written in Python (mostly hierarchical blocks). Until this gets worked out, please bear with us, or better yet, solve it for us! More details on packages in GNU Radio: +\li \ref page_audio \li \ref page_digital -\li \ref page_vocoder \li \ref page_qtgui \li \ref page_uhd +\li \ref page_vocoder */ -- cgit From a27f67c7c8d083d6e07ca10161c0ce93b029ad86 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 14 Oct 2011 17:11:36 -0400 Subject: docs: added a page on PFBs and put them in their own doxygen group. Helpful explination on how to use them and where to find more info. --- docs/doxygen/other/group_defs.dox | 1 + docs/doxygen/other/main_page.dox | 2 +- docs/doxygen/other/pfb_intro.dox | 82 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/doxygen/other/pfb_intro.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 646df6855..6288d1f0a 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -31,6 +31,7 @@ /*! \defgroup qtgui_blk QT Graphical Interfaces */ /*! \defgroup uhd_blk UHD Interface */ /*! \defgroup audio_blk Audio Interface */ +/*! \defgroup pfb_blk Polyphase Filterbank */ /*! * \defgroup base_blk Base classes for GR Blocks diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index f8d0dcf73..7d78bbbbb 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -15,5 +15,5 @@ More details on packages in GNU Radio: \li \ref page_qtgui \li \ref page_uhd \li \ref page_vocoder - +\li \ref page_pfb */ diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox new file mode 100644 index 000000000..8b82d96d7 --- /dev/null +++ b/docs/doxygen/other/pfb_intro.dox @@ -0,0 +1,82 @@ +/*! \page page_pfb Polyphase Filterbanks + +\section Introduction + +Polyphase filterbanks (PFB) are a very powerful set of filtering tools +that can efficiently perform many multi-rate signal processing +tasks. GNU Radio has a set of polyphase filterbank blocks to be used +in all sorts of applications. These blocks and their documentation can +be found in \ref pfb_blk. + +\section Usage + +See the documentation for the individual blocks for details about what +they can do and how they should be used. Furthermore, there are +examples for these blocks in gnuradio-examples/python/pfb. + +The main issue when using the PFB blocks is defining the prototype +filter, which is passed to all of the blocks as a vector of \p +taps. The taps from the prototype filter which get partitioned among +the \p N channels of the channelizer. + +An example of creating a set of filter taps for a PFB channelizer is +found on line 49 of gnuradio-examples/python/pfb/channelizer.py +and reproduced below. Notice that the sample rate is the sample rate +at the input to the channelizer while the bandwidth and transition +width are defined for the channel bandwidths. This makes a fairly long +filter that is then split up between the \p N channels of the PFB. + +\code + self._fs = 9000 # input sample rate + self._M = 9 # Number of channels to channelize + + self._taps = gr.firdes.low_pass_2(1, self._fs, 475.50, 50, + attenuation_dB=100, + window=gr.firdes.WIN_BLACKMAN_hARRIS) +\endcode + +In this example, the signal into the channelizer is sampled at 9 ksps +(complex, so 9 kHz of bandwidth). The filter uses 9 channels, so each +output channel will have a bandwidth and sample rate of 1 kHz. We want +to pass most of the channel, so we define the channel bandwidth to be +a low pass filter with a bandwidth of 475.5 Hz and a transition +bandwidth of 50 Hz, but we have defined this using a sample rate of +the original 9 kHz. The prototype filter has 819 taps to be divided up +between the 9 channels, so each channel uses 91 taps. This is probably +over-kill for a channelizer, and we could reduce the amount of taps +per channel to a couple of dozen with no ill effects. + +The basic rule when defining a set of taps for a PFB block is to think +about the filter running at the highest rate it will see while the +bandwidth is defined for the size of the channels. In the channelizer +case, the highest rate is defined as the rate of the incoming signal, +but in other PFB blocks, this is not so obvious. + +Two very useful blocks to use are the arbitrary resampler and the +clock synchronizer (for PAM signals). These PFBs are defined with a +set number of filters based on the fidelity required from them, not +the rate changes. By default, the \p filter_size is set to 32 for +these blocks, which is a reasonable default for most tasks. Because +the PFB uses this number of filters in the filterbank, the maximum +rate of the bank is defined from this (see the theory of a polyphase +interpolator for a justification of this). So the prototype filter is +defined to use a sample rate of \p filter_size times the signal's +sampling rate. + +A helpful wrapper for the arbitrary resampler is found in +gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py, +which is exposed in Python as blks2.pfb_arb_resampler_ccf and +blks2.pfb_arb_resampler_fff. This block is set up so that the +user only needs to pass it the real number \p rate as the resampling +rate. With just this information, this hierarchical block +automatically creates a filter that fully passes the signal bandwidth +being resampled but does not pass any out-of-band noise. See the code +for this block for details of how the filter is constructed. + +Of course, a user can create his or her own taps and use them in the +arbitrary resampler for more specific requirements. Some of the UHD +examples (gr-uhd/examples) use this ability to create a +received matched filter or channel filter that also resamples the +signal. + +*/ -- cgit From e30b824e9165bff69f09121631c3d5a706cbbd39 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 19 Oct 2011 15:10:58 -0700 Subject: Removing usrp, usrp2, gr-usrp, gr-usrp2. Everything is moving to using UHD. Also removes related M4 and dependency requirements for USRP-related libs. --- docs/doxygen/other/group_defs.dox | 3 --- 1 file changed, 3 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 6288d1f0a..b0b1994ff 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -68,7 +68,4 @@ /*! @} */ -/*! \defgroup usrp USRP */ -/*! \defgroup usrp2 USRP2 */ - /*! \defgroup hardware Misc Hardware Control */ -- cgit From 29299eb3ddadbbbe782127a24e314bbb349422fe Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 21 Oct 2011 18:06:47 -0400 Subject: docs: updating documentation. More build instructions/information in Doxygen. Added logo to doxygen manual, too. --- docs/doxygen/other/build_guide.dox | 135 +++++++++++++++++++++++++++++++++++++ docs/doxygen/other/main_page.dox | 24 ++++++- 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 docs/doxygen/other/build_guide.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox new file mode 100644 index 000000000..207f553a1 --- /dev/null +++ b/docs/doxygen/other/build_guide.dox @@ -0,0 +1,135 @@ +/*! \page page_build Build Instructions and Information + +\section dependencies Dependencies + +The list of GNU Radio dependencies and the minimum required versions, +if any, to build the various GNU Radio components. + +Most of these components do not need to be individually compiled or +installed. Instead, rely on your operating system's package manager or +binary installation process (the apt-get system in Debian and +Ubuntu, yum in RedHat and Fedora, etc.). GNU Radio tries to keep an +up-to-date build guide for the majority of the supported operating +systems on gnuradio.org +(http://gnuradio.org/redmine/projects/gnuradio/wiki/BuildGuide). + +Not all dependencies are required for all components, and not all +components are required for a given installation. The list of required +components is determined by what the user requires from GNU Radio. If, +for example, you do not use any Comedi-based hardware, do not worry +about building gr-comedi. + +\subsection dep_global Global Dependencies +\li git http://code.google.com/p/msysgit +\li cmake http://www.cmake.org/cmake/resources/software.html +\li boost (>= 1.35) http://www.boostpro.com/download +\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html +\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html +\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm + +\subsection dep_python Python Wrappers +\li python (>= 2.5) http://www.python.org/download/ +\li swig (>= 1.3.31) http://www.swig.org/download.html +\li numpy (>= 1.1.0) http://sourceforge.net/projects/numpy/files/NumPy/ + +\subsection dep_docs docs: Building the documentation +\li doxygen (>= 1.5) http://www.stack.nl/~dimitri/doxygen/download.html + +\subsection dep_grc grc: The GNU Radio Companion +\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ +\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html + +\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface +\li qt (>= 4.4) http://qt.nokia.com/downloads/ +\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ +\li pyqt (>= 4.4) http://www.riverbankcomputing.co.uk/software/pyqt/download +\li pyqwt (>= 5.2) http://pyqwt.sourceforge.net/download.html + +\subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface +\li wxpython (>= 2.8) http://www.wxpython.org/ +\li python-lxml (>= 1.3.6) http://lxml.de/ + +\subsection dep_gr_audio gr-audio: Audio Subsystems (system/OS dependent) +\li audio-alsa (>= 0.9) http://www.alsa-project.org +\li audio-jack (>= 0.8) http://jackaudio.org/ +\li portaduio (>= 19) http://www.portaudio.com/ +\li audio-oss (>= 1.0) http://www.opensound.com/oss.html +\li audio-osx +\li audio-windows + +\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface +\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki + +\subsection dep_shd shd: The Symplex Hardware Driver Interface +\li shd (>= 3.0.0) + +\subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display +\li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php + +\subsection dep_gr_comedi gr-comedi: Comedi hardware interface +\li comedilib (>= 0.8) http://www.comedi.org/ + + + +\section build_gr_cmake Building GNU Radio + +GNU Radio is built using the Cmake build system +(http://www.cmake.org/). The standard build method is as follows: + +\code +$ mkdir $(builddir) +$ cd $(builddir) +$ cmake [OPTIONS] $(srcdir) +$ make +$ make test +$ sudo make install +\endcode + +The \$(builddir) is the directory in which the code is built. This +cannot be the same path as where the source code resides. Often, +\$(builddir) is \$(srcdir)/build. + +Options can be used to specify where to find various library or +include file dependencies that are not automatically being found +(-DCMAKE_PREFIX_PATH) or set the prefix +(-DCMAKE_INSTALL_PREFIX=(dir)). + +Components can also be enabled and disabled through the options. For a +component named *gr-comp*, the option to disable would look like: +-DENABLE_GR_COMP=off. The "off" could also be "false" or "no", and +cmake is not case sensitive about these options. Similarly, "true", +"on", or "yes" will turn this component on. All components are enabled +by default. + + +\subsection build_gr_cmake_e100 Building for the E100 + +To build GNU Radio on the Ettus Research E100 embedded platforms, +Cmake has to know that the processors uses the NEON extensions. Use +the + +\code +cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + +\endcode + + +\section build_old_autotools Building Using Old Autotools Method + +As of version 3.5, we have moved to using Cmake as the default, +preferred build system. If for some reason, Cmake fails on your +system, GNU Radio still includes the old autotools build process as a +parallel build method. To build: + +\code +$ cd $(srcdir) +$ ./bootstrap // only if not building from a tarball +$ cd $(builddir) +$ $(srcdir)/configure [options] +$ make [-jN] +$ make check +$ sudo make install +\endcode + +*/ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 7d78bbbbb..0caa0b20f 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -1,14 +1,36 @@ /*! \mainpage +\image html gnuradio-logo.png + Welcome to GNU Radio! -For a list of all GNU Radio C++ blocks, please see C++ Blocks. +For details about GNU Radio and using it, please see the main project page. + +Other information about the project and discussion about GNU Radio, +software radio, and communication theory in general can be found at +the GNU Radio blog. + + +\section build Building GNU Radio + +See the \ref page_build page for details about the project's +dependencies and build process. + + +\section blocks GNU Radio Blocks + +GNU Radio uses discrete signal processing blocks that are connected +together to perform your signal processing application. This manual +contain a list of all GNU Radio C++ Blocks. Please note that at this time, we haven't found an acceptable way to provide unified documentation for the C++ parts of the system and the parts written in Python (mostly hierarchical blocks). Until this gets worked out, please bear with us, or better yet, solve it for us! + +\section toc Manual Contents More details on packages in GNU Radio: \li \ref page_audio \li \ref page_digital -- cgit From de849caeb9d689ab0ffd9d8279ba0cb1af925753 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 20 Oct 2011 09:41:07 -0700 Subject: docs: grabbed support files from ben's repo and my repo --- docs/doxygen/other/group_defs.dox | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index b0b1994ff..6288d1f0a 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -68,4 +68,7 @@ /*! @} */ +/*! \defgroup usrp USRP */ +/*! \defgroup usrp2 USRP2 */ + /*! \defgroup hardware Misc Hardware Control */ -- cgit From 00420d32081d8252bb37142b2be19a8a7c4dc4c4 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 8 Dec 2011 13:48:48 -0800 Subject: Removed autotools, gr-waveform, some cleanup Nick Foster owes Nick Corgan a six-pack of beer! --- docs/doxygen/other/.gitignore | 8 -------- docs/doxygen/other/Makefile.am | 29 ----------------------------- 2 files changed, 37 deletions(-) delete mode 100644 docs/doxygen/other/.gitignore delete mode 100644 docs/doxygen/other/Makefile.am (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/.gitignore b/docs/doxygen/other/.gitignore deleted file mode 100644 index a02b6ff73..000000000 --- a/docs/doxygen/other/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo diff --git a/docs/doxygen/other/Makefile.am b/docs/doxygen/other/Makefile.am deleted file mode 100644 index 82ee0f945..000000000 --- a/docs/doxygen/other/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2001,2004,2010 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -include $(top_srcdir)/Makefile.common - -EXTRA_DIST += \ - doxypy.py \ - group_defs.dox \ - shared_ptr_docstub.h \ - tv-channel-frequencies \ - vector_docstub.h -- cgit From 36dda1f11620c6c9db63036d76a67b3be3f711bc Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 29 Dec 2011 18:30:27 -0500 Subject: digital: added documentation for SNR estimators; made a Doxygen group for them. Also set the alpha value to a default of 0.001; most won't need to change this. --- docs/doxygen/other/group_defs.dox | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 6288d1f0a..facdc2338 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -32,6 +32,7 @@ /*! \defgroup uhd_blk UHD Interface */ /*! \defgroup audio_blk Audio Interface */ /*! \defgroup pfb_blk Polyphase Filterbank */ +/*! \defgroup snr_blk SNR estimators */ /*! * \defgroup base_blk Base classes for GR Blocks -- cgit From 4589b6d6f062e92fd84965eaf47d3fc30bdf516e Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 11 Feb 2012 12:27:45 -0500 Subject: volk: added some documentation to the Doxygen manual explaining Volk and how to use it. --- docs/doxygen/other/main_page.dox | 10 +++ docs/doxygen/other/volk_guide.dox | 161 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 docs/doxygen/other/volk_guide.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 0caa0b20f..68b098943 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -38,4 +38,14 @@ More details on packages in GNU Radio: \li \ref page_uhd \li \ref page_vocoder \li \ref page_pfb + +\section volk_main Using Volk in GNU Radio + +The \ref volk_guide page provides an overview of how to incorporate +and use Volk in GNU Radio blocks. + +Many blocks have already been converted to use Volk in their calls, so +they can also serve as examples. See the gr_complex_to_xxx.h file for +examples of various blocks that make use of Volk. + */ diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox new file mode 100644 index 000000000..d898f3864 --- /dev/null +++ b/docs/doxygen/other/volk_guide.dox @@ -0,0 +1,161 @@ +/*! \page volk_guide Instructions for using Volk in GNU Radio + +\section volk_intro Introduction + +Volk is the Vector-Optimized Library of Kernels. It is a library that +contains kernels of hand-written SIMD code for different mathematical +operations. Since each SIMD architecture can be greatly different and +no compiler has yet come along to handle vectorization properly or +highly efficiently, Volk approaches the problem differently. For each +architecture or platform that a developer wishes to vectorize for, a +new proto-kernel is added to Volk. At runtime, Volk will select the +correct proto-kernel. In this way, the users of Volk call a kernel for +performing the operation that is platform/architecture agnostic. This +allows us to write portable SIMD code. + +Volk kernels are always defined with a 'generic' proto-kernel, which +is written in plain C. With the generic kernel, the kernel becomes +portable to any platform. Kernels are then extended by adding +proto-kernels for new platforms in which they are desired. + +A good example of a Volk kernel with multiple proto-kernels defined is +the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar +multiplication of a vector of floating point numbers (each item in the +vector is multiplied by the same value). This kernel has the following +proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.' + +\code + void volk_32f_s32f_multiply_32f_a_generic + void volk_32f_s32f_multiply_32f_a_sse + void volk_32f_s32f_multiply_32f_a_avx + void volk_32f_s32f_multiply_32f_a_orc +\endcode + +These proto-kernels means that on platforms with AVX support, Volk can +select this option or the SSE option, depending on which is faster. On +other platforms, the ORC SIMD compiler might provide a solution. If +all else fails, Volk can fall back on the generic proto-kernel, which +will always work. + +Just a note on ORC. ORC is a SIMD compiler library that uses a generic +assembly-like language for SIMD commands. Based on the available SIMD +architecture of a system, it will try and compile a good +solution. Tests show that the results of ORC proto-kernels are +generally better than the generic versions but often not as good as +the hand-tuned proto-kernels for a specific SIMD architecture. This +is, of course, to be expected, and ORC provides a nice intermediary +step to performance improvements until a specific hand-tuned +proto-kernel can be made for a given platform. + +See Volk on +gnuradio.org for details on the Volk naming scheme. + + +\section volk_alignment Setting and Using Memory Alignment Information + +For Volk to work as best as possible, we want to use memory-aligned +SIMD calls, which means we have to have some way of knowing and +controlling the alignment of the buffers passed to gr_block's work +function. We set the alignment requirement for SIMD aligned memory +calls with: + +\code + const int alignment_multiple = + volk_get_alignment() / output_item_size; + set_alignment(alignment_multiple); +\endcode + +The Volk function 'volk_get_alignment' provides the alignment of the +the machine architecture. We then base the alignment on the number of +output items required to maintain the alignment, so we divide the +number of alignment bytes by the number of bytes in an output items +(sizeof(float), sizeof(gr_complex), etc.). This value is then set per +block with the 'set_alignment' function. + +Because the scheduler tries to optimize throughput, the number of +items available per call to work will change and depends on the +availability of the read and write buffers. This means that it +sometimes cannot produce a buffer that is properly memory +aligned. This is an inevitable consequence of the scheduler +system. Instead of requiring alignment, the scheduler enforces the +alignment as much as possible, and when a buffer becomes unaligned, +the scheduler will work to correct it as much as possible. If a +block's buffers are unaligned, then, the scheduler sets a flag to +indicate as much so that the block can then decide what best to +do. The next section discusses the use of the aligned/unaligned +information in a gr_block's work function. + + +\section volk_work Using Alignment Properties in Work() + +The buffers passed to work/general_work in a gr_block are not +guaranteed to be aligned, but they will mostly be aligned whenever +possible. When not aligned, the 'is_unaligned()' flag will be set. So +a block can know if its buffers are aligned and make the right +decisions. This looks like: + +\code +int +gr_some_block::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + if(is_unaligned()) { + // do something with unaligned data. This can either be a manual + // handling of the items or a call to an unaligned Volk function. + volk_32f_something_32f_u(out, in, noutput_items); + } + else { + // Buffers are aligned; can call the aligned Volk function. + volk_32f_something_32f_a(out, in, noutput_items); + } + + return noutput_items; +} +\endcode + + + +\section volk_tuning Tuning Volk Performance + +VOLK comes with a profiler that will build a config file for the best +SIMD architecture for your processor. Run volk_profile that is +installed into $PREFIX/bin. This program tests all known VOLK kernels +for each architecture supported by the processor. When finished, it +will write to $HOME/.volk/volk_config the best architecture for the +VOLK function. This file is read when using a function to know the +best version of the function to execute. + +\subsection volk_hand_tuning Hand-Tuning Performance + +If you know a particular architecture works best for your processor, +you can specify the particular architecture to use in the VOLK +preferences file: $HOME/.volk/volk_config + +The file looks like: + +\code + volk_ +\endcode + +Where the "FUNCTION_NAME" is the particular function that you want to +over-ride the default value and "ARCHITECTURE" is the VOLK SIMD +architecture to use (generic, sse, sse2, sse3, avx, etc.). For +example, the following config file tells VOLK to use SSE3 for the +aligned and unaligned versions of a function that multiplies two +complex streams together. + +\code + volk_32fc_x2_multiply_32fc_a sse3 + volk_32fc_x2_multiply_32fc_u sse3 +\endcode + +\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a +volk_config file that sets all architectures to 'generic' as a way to +test the vectorized versus non-vectorized implementations. + +*/ -- cgit From 5fbdd919e9a32710d118fa29018dfb3ffff43ed5 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 14 Feb 2012 09:34:17 -0500 Subject: docs: removing old Doxygen groups (radar and usrp(2)). --- docs/doxygen/other/group_defs.dox | 8 -------- 1 file changed, 8 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index facdc2338..285fbd1a5 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -57,11 +57,6 @@ * ATSC Applications... */ -/*! - * \defgroup radar Radar - * Radar Applications... - */ - /*! * \defgroup pager Pager * Pager Applications @@ -69,7 +64,4 @@ /*! @} */ -/*! \defgroup usrp USRP */ -/*! \defgroup usrp2 USRP2 */ - /*! \defgroup hardware Misc Hardware Control */ -- cgit From 8f8b651fbec99dcdc437f5445974692f7fa09142 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 1 Mar 2012 11:27:07 -0500 Subject: docs: setting up ability to link to example files in the Doxygen manual. Using the PFB channelize.py as a test. --- docs/doxygen/other/pfb_intro.dox | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox index 8b82d96d7..4224aec35 100644 --- a/docs/doxygen/other/pfb_intro.dox +++ b/docs/doxygen/other/pfb_intro.dox @@ -79,4 +79,18 @@ examples (gr-uhd/examples) use this ability to create a received matched filter or channel filter that also resamples the signal. +\section Examples + +The following is an example of the using the channelizer. It creates +the appropriate filter to channelizer 9 channels out of an original +signal that is 9000 Hz wide, so each output channel is now 1000 +Hz. The code then plots the PSD of the original signal to see the +signals in the origina spectrum and then makes 9 plots for each of the +channels. + +NOTE: you need the Scipy and Matplotlib Python modules installed to +run this example. + +\include gnuradio-examples/python/pfb/channelize.py + */ -- cgit From 50acbac3f7cae00f8cfeab44efd7cdc4d41d5018 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 3 Apr 2012 13:12:50 -0400 Subject: docs: adding more info to the doxygen manual's build guide. --- docs/doxygen/other/build_guide.dox | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox index 207f553a1..734fb9e25 100644 --- a/docs/doxygen/other/build_guide.dox +++ b/docs/doxygen/other/build_guide.dox @@ -21,7 +21,7 @@ about building gr-comedi. \subsection dep_global Global Dependencies \li git http://code.google.com/p/msysgit -\li cmake http://www.cmake.org/cmake/resources/software.html +\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html \li boost (>= 1.35) http://www.boostpro.com/download \li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html \li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html @@ -89,6 +89,8 @@ The \$(builddir) is the directory in which the code is built. This cannot be the same path as where the source code resides. Often, \$(builddir) is \$(srcdir)/build. +\subsection Cmake Options + Options can be used to specify where to find various library or include file dependencies that are not automatically being found (-DCMAKE_PREFIX_PATH) or set the prefix @@ -101,6 +103,37 @@ cmake is not case sensitive about these options. Similarly, "true", "on", or "yes" will turn this component on. All components are enabled by default. +An example is -DENABLE_PYTHON=False turns off building any Python or +Swigging components. The result will be the GNU Radio libraries and +C++ programs/applications/examples. No Python or GRC files will be +built or installed. + +The -DENABLE_DEFAULT=False can be used to disable all +components. Individual components can then be selectively turned back +on. For example, just buidling the Volk and Gruel libraries can be +done with this: + +\code +cmake -DENABLE_DEFAULT=Off -DENABLE_VOLK=True -DENABLE_GRUEL=True +\endcode + + +The build type allows you to specify the build as a debug or release +version. Each type sets different flags for different purposes. To set +the build type, use: + +\code +-DCMAKE_BUILD_TYPE="Release"|"Debug" +\endcode + +If not specified, the "Release" mode is the defaulted to. + +"Release" mode sets the '-O3' optimization flag. + +"Debug" mode sets '-g -O2' flags to export debug symbols and reduce +the optimization to make the libraries easier to debug and step +through. + \subsection build_gr_cmake_e100 Building for the E100 -- cgit From 0dec80cb29da6dc4fbf4c349ea5c3399521561da Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 13 Apr 2012 09:47:55 -0400 Subject: Fix some minor warnings. --- docs/doxygen/other/pfb_intro.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox index 4224aec35..01d08b0fa 100644 --- a/docs/doxygen/other/pfb_intro.dox +++ b/docs/doxygen/other/pfb_intro.dox @@ -91,6 +91,6 @@ channels. NOTE: you need the Scipy and Matplotlib Python modules installed to run this example. -\include gnuradio-examples/python/pfb/channelize.py +\include gnuradio-core/src/examples/pfb/channelize.py */ -- cgit From f919f9dcbb54a08e6e26d6c229ce92fb784fa1b2 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 13 Apr 2012 18:36:53 -0400 Subject: Removed whitespace and added dtools/bin/remove-whitespace as a tool to do this in the future. The sed script was provided by Moritz Fischer. --- docs/doxygen/other/build_guide.dox | 2 +- docs/doxygen/other/doxypy.py | 142 +++++++++++++++--------------- docs/doxygen/other/group_defs.dox | 6 +- docs/doxygen/other/tv-channel-frequencies | 6 +- docs/doxygen/other/vector_docstub.h | 2 +- docs/doxygen/other/volk_guide.dox | 2 +- 6 files changed, 80 insertions(+), 80 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox index 734fb9e25..780976d62 100644 --- a/docs/doxygen/other/build_guide.dox +++ b/docs/doxygen/other/build_guide.dox @@ -61,7 +61,7 @@ about building gr-comedi. \li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki \subsection dep_shd shd: The Symplex Hardware Driver Interface -\li shd (>= 3.0.0) +\li shd (>= 3.0.0) \subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display \li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php diff --git a/docs/doxygen/other/doxypy.py b/docs/doxygen/other/doxypy.py index 82fdb6bea..15d3e0824 100755 --- a/docs/doxygen/other/doxypy.py +++ b/docs/doxygen/other/doxypy.py @@ -21,7 +21,7 @@ __website__ = "http://code.foosel.org/doxypy" __author__ = ( "Philippe 'demod' Neumann (doxypy at demod dot org)", - "Gina 'foosel' Haeussge (gina at foosel dot net)" + "Gina 'foosel' Haeussge (gina at foosel dot net)" ) __licenseName__ = "GPL v2" @@ -46,32 +46,32 @@ from optparse import OptionParser, OptionGroup class FSM(object): """Implements a finite state machine. - + Transitions are given as 4-tuples, consisting of an origin state, a target state, a condition for the transition (given as a reference to a function which gets called with a given piece of input) and a pointer to a function - to be called upon the execution of the given transition. + to be called upon the execution of the given transition. """ - + """ @var transitions holds the transitions @var current_state holds the current state @var current_input holds the current input @var current_transition hold the currently active transition """ - + def __init__(self, start_state=None, transitions=[]): self.transitions = transitions self.current_state = start_state self.current_input = None self.current_transition = None - + def setStartState(self, state): self.current_state = state def addTransition(self, from_state, to_state, condition, callback): self.transitions.append([from_state, to_state, condition, callback]) - + def makeTransition(self, input): """ Makes a transition based on the given input. @@ -93,16 +93,16 @@ class FSM(object): class Doxypy(object): def __init__(self): string_prefixes = "[uU]?[rR]?" - + self.start_single_comment_re = re.compile("^\s*%s(''')" % string_prefixes) self.end_single_comment_re = re.compile("(''')\s*$") - + self.start_double_comment_re = re.compile("^\s*%s(\"\"\")" % string_prefixes) self.end_double_comment_re = re.compile("(\"\"\")\s*$") - + self.single_comment_re = re.compile("^\s*%s(''').*(''')\s*$" % string_prefixes) self.double_comment_re = re.compile("^\s*%s(\"\"\").*(\"\"\")\s*$" % string_prefixes) - + self.defclass_re = re.compile("^(\s*)(def .+:|class .+:)") self.empty_re = re.compile("^\s*$") self.hashline_re = re.compile("^\s*#.*$") @@ -110,16 +110,16 @@ class Doxypy(object): self.multiline_defclass_start_re = re.compile("^(\s*)(def|class)(\s.*)?$") self.multiline_defclass_end_re = re.compile(":\s*$") - + ## Transition list format # ["FROM", "TO", condition, action] transitions = [ ### FILEHEAD - + # single line comments ["FILEHEAD", "FILEHEAD", self.single_comment_re.search, self.appendCommentLine], ["FILEHEAD", "FILEHEAD", self.double_comment_re.search, self.appendCommentLine], - + # multiline comments ["FILEHEAD", "FILEHEAD_COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine], ["FILEHEAD_COMMENT_SINGLE", "FILEHEAD", self.end_single_comment_re.search, self.appendCommentLine], @@ -127,21 +127,21 @@ class Doxypy(object): ["FILEHEAD", "FILEHEAD_COMMENT_DOUBLE", self.start_double_comment_re.search, self.appendCommentLine], ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD", self.end_double_comment_re.search, self.appendCommentLine], ["FILEHEAD_COMMENT_DOUBLE", "FILEHEAD_COMMENT_DOUBLE", self.catchall, self.appendCommentLine], - + # other lines ["FILEHEAD", "FILEHEAD", self.empty_re.search, self.appendFileheadLine], ["FILEHEAD", "FILEHEAD", self.hashline_re.search, self.appendFileheadLine], ["FILEHEAD", "FILEHEAD", self.importline_re.search, self.appendFileheadLine], ["FILEHEAD", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch], - ["FILEHEAD", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch], + ["FILEHEAD", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch], ["FILEHEAD", "DEFCLASS_BODY", self.catchall, self.appendFileheadLine], ### DEFCLASS - + # single line comments ["DEFCLASS", "DEFCLASS_BODY", self.single_comment_re.search, self.appendCommentLine], ["DEFCLASS", "DEFCLASS_BODY", self.double_comment_re.search, self.appendCommentLine], - + # multiline comments ["DEFCLASS", "COMMENT_SINGLE", self.start_single_comment_re.search, self.appendCommentLine], ["COMMENT_SINGLE", "DEFCLASS_BODY", self.end_single_comment_re.search, self.appendCommentLine], @@ -155,9 +155,9 @@ class Doxypy(object): ["DEFCLASS", "DEFCLASS", self.defclass_re.search, self.resetCommentSearch], ["DEFCLASS", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.resetCommentSearch], ["DEFCLASS", "DEFCLASS_BODY", self.catchall, self.stopCommentSearch], - + ### DEFCLASS_BODY - + ["DEFCLASS_BODY", "DEFCLASS", self.defclass_re.search, self.startCommentSearch], ["DEFCLASS_BODY", "DEFCLASS_MULTI", self.multiline_defclass_start_re.search, self.startCommentSearch], ["DEFCLASS_BODY", "DEFCLASS_BODY", self.catchall, self.appendNormalLine], @@ -166,10 +166,10 @@ class Doxypy(object): ["DEFCLASS_MULTI", "DEFCLASS", self.multiline_defclass_end_re.search, self.appendDefclassLine], ["DEFCLASS_MULTI", "DEFCLASS_MULTI", self.catchall, self.appendDefclassLine], ] - + self.fsm = FSM("FILEHEAD", transitions) self.outstream = sys.stdout - + self.output = [] self.comment = [] self.filehead = [] @@ -178,22 +178,22 @@ class Doxypy(object): def __closeComment(self): """Appends any open comment block and triggering block to the output.""" - + if options.autobrief: if len(self.comment) == 1 \ or (len(self.comment) > 2 and self.comment[1].strip() == ''): self.comment[0] = self.__docstringSummaryToBrief(self.comment[0]) - + if self.comment: block = self.makeCommentBlock() self.output.extend(block) - + if self.defclass: self.output.extend(self.defclass) def __docstringSummaryToBrief(self, line): """Adds \\brief to the docstrings summary line. - + A \\brief is prepended, provided no other doxygen command is at the start of the line. """ @@ -202,7 +202,7 @@ class Doxypy(object): return "\\brief " + line else: return line - + def __flushBuffer(self): """Flushes the current outputbuffer to the outstream.""" if self.output: @@ -212,8 +212,8 @@ class Doxypy(object): print >>self.outstream, "\n".join(self.output) self.outstream.flush() except IOError: - # Fix for FS#33. Catches "broken pipe" when doxygen closes - # stdout prematurely upon usage of INPUT_FILTER, INLINE_SOURCES + # Fix for FS#33. Catches "broken pipe" when doxygen closes + # stdout prematurely upon usage of INPUT_FILTER, INLINE_SOURCES # and FILTER_SOURCE_FILES. pass self.output = [] @@ -221,20 +221,20 @@ class Doxypy(object): def catchall(self, input): """The catchall-condition, always returns true.""" return True - + def resetCommentSearch(self, match): """Restarts a new comment search for a different triggering line. - + Closes the current commentblock and starts a new comment search. """ if options.debug: - print >>sys.stderr, "# CALLBACK: resetCommentSearch" + print >>sys.stderr, "# CALLBACK: resetCommentSearch" self.__closeComment() self.startCommentSearch(match) - + def startCommentSearch(self, match): """Starts a new comment search. - + Saves the triggering line, resets the current comment and saves the current indentation. """ @@ -243,41 +243,41 @@ class Doxypy(object): self.defclass = [self.fsm.current_input] self.comment = [] self.indent = match.group(1) - + def stopCommentSearch(self, match): """Stops a comment search. - + Closes the current commentblock, resets the triggering line and appends the current line to the output. """ if options.debug: - print >>sys.stderr, "# CALLBACK: stopCommentSearch" + print >>sys.stderr, "# CALLBACK: stopCommentSearch" self.__closeComment() - + self.defclass = [] self.output.append(self.fsm.current_input) - + def appendFileheadLine(self, match): """Appends a line in the FILEHEAD state. - + Closes the open comment block, resets it and appends the current line. - """ + """ if options.debug: - print >>sys.stderr, "# CALLBACK: appendFileheadLine" + print >>sys.stderr, "# CALLBACK: appendFileheadLine" self.__closeComment() self.comment = [] self.output.append(self.fsm.current_input) def appendCommentLine(self, match): """Appends a comment line. - + The comment delimiter is removed from multiline start and ends as well as singleline comments. """ if options.debug: - print >>sys.stderr, "# CALLBACK: appendCommentLine" + print >>sys.stderr, "# CALLBACK: appendCommentLine" (from_state, to_state, condition, callback) = self.fsm.current_transition - + # single line comment if (from_state == "DEFCLASS" and to_state == "DEFCLASS_BODY") \ or (from_state == "FILEHEAD" and to_state == "FILEHEAD"): @@ -308,19 +308,19 @@ class Doxypy(object): else: # just append the comment line self.comment.append(self.fsm.current_input) - + def appendNormalLine(self, match): """Appends a line to the output.""" if options.debug: - print >>sys.stderr, "# CALLBACK: appendNormalLine" + print >>sys.stderr, "# CALLBACK: appendNormalLine" self.output.append(self.fsm.current_input) - + def appendDefclassLine(self, match): """Appends a line to the triggering block.""" if options.debug: - print >>sys.stderr, "# CALLBACK: appendDefclassLine" + print >>sys.stderr, "# CALLBACK: appendDefclassLine" self.defclass.append(self.fsm.current_input) - + def makeCommentBlock(self): """Indents the current comment block with respect to the current indentation level. @@ -329,59 +329,59 @@ class Doxypy(object): """ doxyStart = "##" commentLines = self.comment - + commentLines = map(lambda x: "%s# %s" % (self.indent, x), commentLines) l = [self.indent + doxyStart] l.extend(commentLines) - + return l - + def parse(self, input): """Parses a python file given as input string and returns the doxygen- compatible representation. - + @param input the python code to parse @returns the modified python code - """ + """ lines = input.split("\n") - + for line in lines: self.fsm.makeTransition(line) - + if self.fsm.current_state == "DEFCLASS": self.__closeComment() - + return "\n".join(self.output) - + def parseFile(self, filename): """Parses a python file given as input string and returns the doxygen- compatible representation. - + @param input the python code to parse @returns the modified python code - """ + """ f = open(filename, 'r') - + for line in f: self.parseLine(line.rstrip('\r\n')) if self.fsm.current_state == "DEFCLASS": self.__closeComment() self.__flushBuffer() f.close() - + def parseLine(self, line): - """Parse one line of python and flush the resulting output to the + """Parse one line of python and flush the resulting output to the outstream. - + @param line the python code line to parse """ self.fsm.makeTransition(line) self.__flushBuffer() - + def optParse(): """Parses commandline options.""" parser = OptionParser(prog=__applicationName__, version="%prog " + __version__) - + parser.set_usage("%prog [options] filename") parser.add_option("--autobrief", action="store_true", dest="autobrief", @@ -391,19 +391,19 @@ def optParse(): action="store_true", dest="debug", help="enable debug output on stderr" ) - + ## parse options global options (options, filename) = parser.parse_args() - + if not filename: print >>sys.stderr, "No filename given." sys.exit(-1) - + return filename[0] def main(): - """Starts the parser on the file given by the filename as the first + """Starts the parser on the file given by the filename as the first argument on the commandline. """ filename = optParse() diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 285fbd1a5..213486b7a 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -1,7 +1,7 @@ /*! * \defgroup block GNU Radio C++ Signal Processing Blocks * \brief All C++ blocks that can be used in GR graphs are listed here or in - * the subcategories below. + * the subcategories below. * * Sorry, at this time the Python hierarchical blocks are not included * in this index. @@ -34,7 +34,7 @@ /*! \defgroup pfb_blk Polyphase Filterbank */ /*! \defgroup snr_blk SNR estimators */ -/*! +/*! * \defgroup base_blk Base classes for GR Blocks * \brief All C++ blocks are derived from these base classes */ @@ -58,7 +58,7 @@ */ /*! - * \defgroup pager Pager + * \defgroup pager Pager * Pager Applications */ diff --git a/docs/doxygen/other/tv-channel-frequencies b/docs/doxygen/other/tv-channel-frequencies index e2780eca9..8613124f7 100644 --- a/docs/doxygen/other/tv-channel-frequencies +++ b/docs/doxygen/other/tv-channel-frequencies @@ -1,13 +1,13 @@ # These are the center frequencies in MHz for North American broadcast # TV channels. Each channel is 6 MHz wide, hence the bottom edge of the # channel is 3 MHz below the value in this table. -# +# # For NTSC (Analog) TV, the picture carrier is 1.25 MHz up from the # bottom edge. NTSC has the FM audio at bottom + 5.75 and the spike is easily # visible. -# +# # For ATSC, the pilot tone is 0.31 MHz up from the bottom. -# +# # 2 57.00 3 63.00 diff --git a/docs/doxygen/other/vector_docstub.h b/docs/doxygen/other/vector_docstub.h index 139ce651d..062e08d30 100644 --- a/docs/doxygen/other/vector_docstub.h +++ b/docs/doxygen/other/vector_docstub.h @@ -12,5 +12,5 @@ namespace std public: T *p; }; - + } // namespace std diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox index d898f3864..24882ed1a 100644 --- a/docs/doxygen/other/volk_guide.dox +++ b/docs/doxygen/other/volk_guide.dox @@ -24,7 +24,7 @@ multiplication of a vector of floating point numbers (each item in the vector is multiplied by the same value). This kernel has the following proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.' -\code +\code void volk_32f_s32f_multiply_32f_a_generic void volk_32f_s32f_multiply_32f_a_sse void volk_32f_s32f_multiply_32f_a_avx -- cgit From 62eb0520ba866cc2eb7a4aa3e0ba0cdd325b6c0a Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 22 Apr 2012 20:59:42 -0400 Subject: docs: updating build dependency and building instructions. --- docs/doxygen/other/build_guide.dox | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox index 780976d62..629a0f89f 100644 --- a/docs/doxygen/other/build_guide.dox +++ b/docs/doxygen/other/build_guide.dox @@ -19,13 +19,16 @@ components is determined by what the user requires from GNU Radio. If, for example, you do not use any Comedi-based hardware, do not worry about building gr-comedi. +Before trying to build these from source, please try your system's +installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.) +first. Most recent systems have these packages available. + \subsection dep_global Global Dependencies \li git http://code.google.com/p/msysgit \li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html \li boost (>= 1.35) http://www.boostpro.com/download \li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html \li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html -\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm \subsection dep_python Python Wrappers \li python (>= 2.5) http://www.python.org/download/ @@ -39,6 +42,9 @@ about building gr-comedi. \li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ \li pygtk (>= 2.10) http://www.pygtk.org/downloads.html +\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks +\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm + \subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface \li qt (>= 4.4) http://qt.nokia.com/downloads/ \li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ @@ -57,6 +63,10 @@ about building gr-comedi. \li audio-osx \li audio-windows +It is not necessary to satisfy all of these dependencies; just the +one(s) that are right for your system. On Linux, don't expect +audio-osx and audio-windows to be either satisfied or built. + \subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface \li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki @@ -146,23 +156,3 @@ cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ \endcode - - -\section build_old_autotools Building Using Old Autotools Method - -As of version 3.5, we have moved to using Cmake as the default, -preferred build system. If for some reason, Cmake fails on your -system, GNU Radio still includes the old autotools build process as a -parallel build method. To build: - -\code -$ cd $(srcdir) -$ ./bootstrap // only if not building from a tarball -$ cd $(builddir) -$ $(srcdir)/configure [options] -$ make [-jN] -$ make check -$ sudo make install -\endcode - -*/ -- cgit From b629a998bdf0ff88af6f113bd605059ebd61efc8 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 4 Jun 2012 18:24:52 -0400 Subject: docs: added a description of a basic flowgraph to the manual's main page. Also a brief discussion of throughput/latency and how to use the max_noutput_items methods to control them. --- docs/doxygen/other/main_page.dox | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 68b098943..4912a5411 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -39,6 +39,106 @@ More details on packages in GNU Radio: \li \ref page_vocoder \li \ref page_pfb + +\section flowgraph Operating a Flowgraph + +The basic data structure in GNU Radio is the flowgraph, which +represents the connections of the blocks through which a continuous +stream of samples flows. The concept of a flowgraph is an acyclic +directional graph with one or more source blocks (to insert samples +into the flowgraph), one or more sink blocks (to terminate or export +samples from the flowgraph), and any signal processing blocks in +between. + +A program must at least create a GNU Radio 'top_block', which +represents the top-most structure of the flowgraph. The top blocks +provide the overall control and hold methods such as 'start,' 'stop,' +and 'wait.' + +The general construction of a GNU Radio application is to create a top +block, instantiate the blocks, connect the blocks together, and then +start the top block. The following program shows how this is done. A +single source and sink are used with a FIR filter between them. + +\code + from gnuradio import gr, filter + + class my_topblock(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + amp = 1 + taps = filter.firdes.low_pass(1, 1, 0.1, 0.01) + + self.src = gr.noise_source_c(gr.GR_GAUSSIAN, amp) + self.flt = filter.fir_filter_ccf(1, taps) + self.snk = gr.null_sink(gr.sizeof_gr_complex) + + self.connect(self.src, self.flt, self.snk) + + if __name__ == "__main__": + tb = my_topblock() + tb.start() + tb.wait() +\endcode + +The 'tb.start()' starts the data flowing through the flowgraph while +the 'tb.wait()' is the equivalent of a thread's 'join' operation and +blocks until the top block is done. + +An alternative to using the 'start' and 'wait' methods, a 'run' method is +also provided for convenience that is a blocking start call; +equivalent to the above 'start' followed by a 'wait.' + + +\subsection latency Latency and Throughput + +By default, GNU Radio runs a scheduler that attempts to optimize +throughput. Using a dynamic scheduler, blocks in a flowgraph pass +chunks of items from sources to sinks. The sizes of these chunks will +vary depending on the speed of processing. For each block, the number +of items is can process is dependent on how much space it has in its +output buffer(s) and how many items are available on the input +buffer(s). + +The consequence of this is that often a block may be called with a very +large number of items to process (several thousand). In terms of +speed, this is efficient since now the majority of the processing time +is taken up with processing samples. Smaller chunks mean more calls +into the scheduler to retrieve more data. The downside to this is that +it can lead to large latency while a block is processing a large chunk +of data. + +To combat this problem, the top block can be passed a limit on the +number of output items a block will ever receive. A block may get less +than this number, but never more, and so it serves as an upper limit +to the latency any block will exhibit. By limiting the number of items +per call to a block, though, we increase the overhead of the +scheduler, and so reduce the overall efficiency of the application. + +To set the maximum number of output items, we pass a value into the +'start' or 'run' method of the top block: + +\code + tb.start(1000) + tb.wait() +or + tb.run(1000) +\endcode + +Using this method, we place a global restriction on the size of items +to all blocks. Each block, though, has the ability to overwrite this +with its own limit. Using the 'set_max_noutput_items(m)' method for an +individual block will overwrite the global setting. For example, in +the following code, the global setting is 1000 items max, except for +the FIR filter, which can receive up to 2000 items. + +\code + tb.flt.set_max_noutput_items(2000) + tb.run(1000) +\endcode + + \section volk_main Using Volk in GNU Radio The \ref volk_guide page provides an overview of how to incorporate @@ -48,4 +148,5 @@ Many blocks have already been converted to use Volk in their calls, so they can also serve as examples. See the gr_complex_to_xxx.h file for examples of various blocks that make use of Volk. + */ -- cgit From 9c5cd068c1414f1112ab41708833c0fbc267c4d0 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 4 Jun 2012 20:23:01 -0400 Subject: docs: added section explaining the basics of reconfiguring a flowgraph. --- docs/doxygen/other/main_page.dox | 138 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 7 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 4912a5411..1c4a60b3a 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -55,10 +55,11 @@ represents the top-most structure of the flowgraph. The top blocks provide the overall control and hold methods such as 'start,' 'stop,' and 'wait.' -The general construction of a GNU Radio application is to create a top -block, instantiate the blocks, connect the blocks together, and then -start the top block. The following program shows how this is done. A -single source and sink are used with a FIR filter between them. +The general construction of a GNU Radio application is to create a +gr_top_block, instantiate the blocks, connect the blocks together, and +then start the gr_top_block. The following program shows how this is +done. A single source and sink are used with a FIR filter between +them. \code from gnuradio import gr, filter @@ -84,7 +85,7 @@ single source and sink are used with a FIR filter between them. The 'tb.start()' starts the data flowing through the flowgraph while the 'tb.wait()' is the equivalent of a thread's 'join' operation and -blocks until the top block is done. +blocks until the gr_top_block is done. An alternative to using the 'start' and 'wait' methods, a 'run' method is also provided for convenience that is a blocking start call; @@ -109,7 +110,7 @@ into the scheduler to retrieve more data. The downside to this is that it can lead to large latency while a block is processing a large chunk of data. -To combat this problem, the top block can be passed a limit on the +To combat this problem, the gr_top_block can be passed a limit on the number of output items a block will ever receive. A block may get less than this number, but never more, and so it serves as an upper limit to the latency any block will exhibit. By limiting the number of items @@ -117,7 +118,7 @@ per call to a block, though, we increase the overhead of the scheduler, and so reduce the overall efficiency of the application. To set the maximum number of output items, we pass a value into the -'start' or 'run' method of the top block: +'start' or 'run' method of the gr_top_block: \code tb.start(1000) @@ -139,6 +140,129 @@ the FIR filter, which can receive up to 2000 items. \endcode +\section reconfigure Reconfiguring Flowgraphs + +It is possible to reconfigure the flowgraph at runtime. The +reconfiguration is meant for changes in the flowgraph structure, not +individual parameter settings of the blocks. For example, changing the +constant in a gr_add_const_cc block can be done while the flowgraph is +running using the 'set_k(k)' method. + +Reconfiguration is done by locking the flowgraph, which stops it from +running and processing data, performing the reconfiguration, and then +restarting the graph by unlocking it. + +The following example code shows a graph that first adds two +gr_noise_source_c blocks and then replaces the gr_add_cc block with a +gr_sub_cc block to then subtract the sources. + +\code +from gnuradio import gr +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.add = gr.add_cc() + self.sub = gr.sub_cc() + self.head = gr.head(gr.sizeof_gr_complex, 1000000) + self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + tb = mytb() + tb.start() + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block and restart + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + +During reconfiguration, the maximum noutput_items value can be changed +either globally using the 'set_max_noutput_items(m)' on the gr_top_block +object or locally using the 'set_max_noutput_items(m)' on any given +block object. + +A block also has a 'unset_max_noutput_items()' method that unsets the +local max noutput_items value so that block reverts back to using the +global value. + +The following example expands the previous example but sets and resets +the max noutput_items both locally and globally. + +\code +from gnuradio import gr +import time + +class mytb(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1) + self.add = gr.add_cc() + self.sub = gr.sub_cc() + self.head = gr.head(gr.sizeof_gr_complex, 1000000) + self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc") + + self.connect(self.src0, (self.add,0)) + self.connect(self.src1, (self.add,1)) + self.connect(self.add, self.head) + self.connect(self.head, self.snk) + +def main(): + # Start the gr_top_block after setting some max noutput_items. + tb = mytb() + tb.src1.set_max_noutput_items(2000) + tb.start(100) + time.sleep(0.01) + + # Stop flowgraph and disconnect the add block + tb.lock() + + tb.disconnect(tb.add, tb.head) + tb.disconnect(tb.src0, (tb.add,0)) + tb.disconnect(tb.src1, (tb.add,1)) + + # Connect the sub block + tb.connect(tb.sub, tb.head) + tb.connect(tb.src0, (tb.sub,0)) + tb.connect(tb.src1, (tb.sub,1)) + + # Set new max_noutput_items for the gr_top_block + # and unset the local value for src1 + tb.set_max_noutput_items(1000) + tb.src1.unset_max_noutput_items() + tb.unlock() + + tb.wait() + +if __name__ == "__main__": + main() +\endcode + + \section volk_main Using Volk in GNU Radio The \ref volk_guide page provides an overview of how to incorporate -- cgit From ec30d89449f48fdd2f88420b4c87aba2e1a5abd1 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 10 Jun 2012 12:43:06 -0400 Subject: volk: make sure the alignment call for a block passes at least 1. For machines with an alignment of 1, the blocks were truncating the aligment to 0. This makes sure that it gets set to a minimum of 1. --- docs/doxygen/other/volk_guide.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox index 24882ed1a..0e444ebba 100644 --- a/docs/doxygen/other/volk_guide.dox +++ b/docs/doxygen/other/volk_guide.dox @@ -63,7 +63,7 @@ calls with: \code const int alignment_multiple = volk_get_alignment() / output_item_size; - set_alignment(alignment_multiple); + set_alignment(std::max(1,alignment_multiple)); \endcode The Volk function 'volk_get_alignment' provides the alignment of the -- cgit From 743745f0fbb8c31b919bada25dab91dfeab5e129 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 3 Sep 2012 14:09:06 -0400 Subject: docs: reworking doc into one extra dox file for easier linking. build_guide was not being found properly. Putting these together fixes that. --- docs/doxygen/other/build_guide.dox | 158 ------------------ docs/doxygen/other/extra_pages.dox | 326 +++++++++++++++++++++++++++++++++++++ docs/doxygen/other/main_page.dox | 2 +- docs/doxygen/other/volk_guide.dox | 161 ------------------ 4 files changed, 327 insertions(+), 320 deletions(-) delete mode 100644 docs/doxygen/other/build_guide.dox create mode 100644 docs/doxygen/other/extra_pages.dox delete mode 100644 docs/doxygen/other/volk_guide.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox deleted file mode 100644 index 629a0f89f..000000000 --- a/docs/doxygen/other/build_guide.dox +++ /dev/null @@ -1,158 +0,0 @@ -/*! \page page_build Build Instructions and Information - -\section dependencies Dependencies - -The list of GNU Radio dependencies and the minimum required versions, -if any, to build the various GNU Radio components. - -Most of these components do not need to be individually compiled or -installed. Instead, rely on your operating system's package manager or -binary installation process (the apt-get system in Debian and -Ubuntu, yum in RedHat and Fedora, etc.). GNU Radio tries to keep an -up-to-date build guide for the majority of the supported operating -systems on gnuradio.org -(http://gnuradio.org/redmine/projects/gnuradio/wiki/BuildGuide). - -Not all dependencies are required for all components, and not all -components are required for a given installation. The list of required -components is determined by what the user requires from GNU Radio. If, -for example, you do not use any Comedi-based hardware, do not worry -about building gr-comedi. - -Before trying to build these from source, please try your system's -installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.) -first. Most recent systems have these packages available. - -\subsection dep_global Global Dependencies -\li git http://code.google.com/p/msysgit -\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html -\li boost (>= 1.35) http://www.boostpro.com/download -\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html -\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html - -\subsection dep_python Python Wrappers -\li python (>= 2.5) http://www.python.org/download/ -\li swig (>= 1.3.31) http://www.swig.org/download.html -\li numpy (>= 1.1.0) http://sourceforge.net/projects/numpy/files/NumPy/ - -\subsection dep_docs docs: Building the documentation -\li doxygen (>= 1.5) http://www.stack.nl/~dimitri/doxygen/download.html - -\subsection dep_grc grc: The GNU Radio Companion -\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ -\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html - -\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks -\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm - -\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface -\li qt (>= 4.4) http://qt.nokia.com/downloads/ -\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ -\li pyqt (>= 4.4) http://www.riverbankcomputing.co.uk/software/pyqt/download -\li pyqwt (>= 5.2) http://pyqwt.sourceforge.net/download.html - -\subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface -\li wxpython (>= 2.8) http://www.wxpython.org/ -\li python-lxml (>= 1.3.6) http://lxml.de/ - -\subsection dep_gr_audio gr-audio: Audio Subsystems (system/OS dependent) -\li audio-alsa (>= 0.9) http://www.alsa-project.org -\li audio-jack (>= 0.8) http://jackaudio.org/ -\li portaduio (>= 19) http://www.portaudio.com/ -\li audio-oss (>= 1.0) http://www.opensound.com/oss.html -\li audio-osx -\li audio-windows - -It is not necessary to satisfy all of these dependencies; just the -one(s) that are right for your system. On Linux, don't expect -audio-osx and audio-windows to be either satisfied or built. - -\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface -\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki - -\subsection dep_shd shd: The Symplex Hardware Driver Interface -\li shd (>= 3.0.0) - -\subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display -\li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php - -\subsection dep_gr_comedi gr-comedi: Comedi hardware interface -\li comedilib (>= 0.8) http://www.comedi.org/ - - - -\section build_gr_cmake Building GNU Radio - -GNU Radio is built using the Cmake build system -(http://www.cmake.org/). The standard build method is as follows: - -\code -$ mkdir $(builddir) -$ cd $(builddir) -$ cmake [OPTIONS] $(srcdir) -$ make -$ make test -$ sudo make install -\endcode - -The \$(builddir) is the directory in which the code is built. This -cannot be the same path as where the source code resides. Often, -\$(builddir) is \$(srcdir)/build. - -\subsection Cmake Options - -Options can be used to specify where to find various library or -include file dependencies that are not automatically being found -(-DCMAKE_PREFIX_PATH) or set the prefix -(-DCMAKE_INSTALL_PREFIX=(dir)). - -Components can also be enabled and disabled through the options. For a -component named *gr-comp*, the option to disable would look like: --DENABLE_GR_COMP=off. The "off" could also be "false" or "no", and -cmake is not case sensitive about these options. Similarly, "true", -"on", or "yes" will turn this component on. All components are enabled -by default. - -An example is -DENABLE_PYTHON=False turns off building any Python or -Swigging components. The result will be the GNU Radio libraries and -C++ programs/applications/examples. No Python or GRC files will be -built or installed. - -The -DENABLE_DEFAULT=False can be used to disable all -components. Individual components can then be selectively turned back -on. For example, just buidling the Volk and Gruel libraries can be -done with this: - -\code -cmake -DENABLE_DEFAULT=Off -DENABLE_VOLK=True -DENABLE_GRUEL=True -\endcode - - -The build type allows you to specify the build as a debug or release -version. Each type sets different flags for different purposes. To set -the build type, use: - -\code --DCMAKE_BUILD_TYPE="Release"|"Debug" -\endcode - -If not specified, the "Release" mode is the defaulted to. - -"Release" mode sets the '-O3' optimization flag. - -"Debug" mode sets '-g -O2' flags to export debug symbols and reduce -the optimization to make the libraries easier to debug and step -through. - - -\subsection build_gr_cmake_e100 Building for the E100 - -To build GNU Radio on the Ettus Research E100 embedded platforms, -Cmake has to know that the processors uses the NEON extensions. Use -the - -\code -cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ - -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ - -\endcode diff --git a/docs/doxygen/other/extra_pages.dox b/docs/doxygen/other/extra_pages.dox new file mode 100644 index 000000000..d40c692e0 --- /dev/null +++ b/docs/doxygen/other/extra_pages.dox @@ -0,0 +1,326 @@ +/*! \page build_guide Build Instructions and Information + +\section dependencies Dependencies + +The list of GNU Radio dependencies and the minimum required versions, +if any, to build the various GNU Radio components. + +Most of these components do not need to be individually compiled or +installed. Instead, rely on your operating system's package manager or +binary installation process (the apt-get system in Debian and +Ubuntu, yum in RedHat and Fedora, etc.). GNU Radio tries to keep an +up-to-date build guide for the majority of the supported operating +systems on gnuradio.org +(http://gnuradio.org/redmine/projects/gnuradio/wiki/BuildGuide). + +Not all dependencies are required for all components, and not all +components are required for a given installation. The list of required +components is determined by what the user requires from GNU Radio. If, +for example, you do not use any Comedi-based hardware, do not worry +about building gr-comedi. + +Before trying to build these from source, please try your system's +installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.) +first. Most recent systems have these packages available. + +\subsection dep_global Global Dependencies +\li git http://code.google.com/p/msysgit +\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html +\li boost (>= 1.35) http://www.boostpro.com/download +\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html +\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html + +\subsection dep_python Python Wrappers +\li python (>= 2.5) http://www.python.org/download/ +\li swig (>= 1.3.31) http://www.swig.org/download.html +\li numpy (>= 1.1.0) http://sourceforge.net/projects/numpy/files/NumPy/ + +\subsection dep_docs docs: Building the documentation +\li doxygen (>= 1.5) http://www.stack.nl/~dimitri/doxygen/download.html + +\subsection dep_grc grc: The GNU Radio Companion +\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/ +\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html + +\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks +\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm + +\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface +\li qt (>= 4.4) http://qt.nokia.com/downloads/ +\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/ +\li pyqt (>= 4.4) http://www.riverbankcomputing.co.uk/software/pyqt/download +\li pyqwt (>= 5.2) http://pyqwt.sourceforge.net/download.html + +\subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface +\li wxpython (>= 2.8) http://www.wxpython.org/ +\li python-lxml (>= 1.3.6) http://lxml.de/ + +\subsection dep_gr_audio gr-audio: Audio Subsystems (system/OS dependent) +\li audio-alsa (>= 0.9) http://www.alsa-project.org +\li audio-jack (>= 0.8) http://jackaudio.org/ +\li portaduio (>= 19) http://www.portaudio.com/ +\li audio-oss (>= 1.0) http://www.opensound.com/oss.html +\li audio-osx +\li audio-windows + +It is not necessary to satisfy all of these dependencies; just the +one(s) that are right for your system. On Linux, don't expect +audio-osx and audio-windows to be either satisfied or built. + +\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface +\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki + +\subsection dep_shd shd: The Symplex Hardware Driver Interface +\li shd (>= 3.0.0) + +\subsection dep_gr_video_sdl gr-video-sdl: PAL and NTSC display +\li SDL (>= 1.2.0) http://www.libsdl.org/download-1.2.php + +\subsection dep_gr_comedi gr-comedi: Comedi hardware interface +\li comedilib (>= 0.8) http://www.comedi.org/ + + + +\section build_gr_cmake Building GNU Radio + +GNU Radio is built using the Cmake build system +(http://www.cmake.org/). The standard build method is as follows: + +\code +$ mkdir $(builddir) +$ cd $(builddir) +$ cmake [OPTIONS] $(srcdir) +$ make +$ make test +$ sudo make install +\endcode + +The \$(builddir) is the directory in which the code is built. This +cannot be the same path as where the source code resides. Often, +\$(builddir) is \$(srcdir)/build. + +\subsection Cmake Options + +Options can be used to specify where to find various library or +include file dependencies that are not automatically being found +(-DCMAKE_PREFIX_PATH) or set the prefix +(-DCMAKE_INSTALL_PREFIX=(dir)). + +Components can also be enabled and disabled through the options. For a +component named *gr-comp*, the option to disable would look like: +-DENABLE_GR_COMP=off. The "off" could also be "false" or "no", and +cmake is not case sensitive about these options. Similarly, "true", +"on", or "yes" will turn this component on. All components are enabled +by default. + +An example is -DENABLE_PYTHON=False turns off building any Python or +Swigging components. The result will be the GNU Radio libraries and +C++ programs/applications/examples. No Python or GRC files will be +built or installed. + +The -DENABLE_DEFAULT=False can be used to disable all +components. Individual components can then be selectively turned back +on. For example, just buidling the Volk and Gruel libraries can be +done with this: + +\code +cmake -DENABLE_DEFAULT=Off -DENABLE_VOLK=True -DENABLE_GRUEL=True +\endcode + + +The build type allows you to specify the build as a debug or release +version. Each type sets different flags for different purposes. To set +the build type, use: + +\code +-DCMAKE_BUILD_TYPE="Release"|"Debug" +\endcode + +If not specified, the "Release" mode is the defaulted to. + +"Release" mode sets the '-O3' optimization flag. + +"Debug" mode sets '-g -O2' flags to export debug symbols and reduce +the optimization to make the libraries easier to debug and step +through. + + +\subsection build_gr_cmake_e100 Building for the E100 + +To build GNU Radio on the Ettus Research E100 embedded platforms, +Cmake has to know that the processors uses the NEON extensions. Use +the + +\code +cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + -DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \ + +\endcode + +*/ + + + +/*! \page volk_guide Instructions for using Volk in GNU Radio + +\section volk_intro Introduction + +Volk is the Vector-Optimized Library of Kernels. It is a library that +contains kernels of hand-written SIMD code for different mathematical +operations. Since each SIMD architecture can be greatly different and +no compiler has yet come along to handle vectorization properly or +highly efficiently, Volk approaches the problem differently. For each +architecture or platform that a developer wishes to vectorize for, a +new proto-kernel is added to Volk. At runtime, Volk will select the +correct proto-kernel. In this way, the users of Volk call a kernel for +performing the operation that is platform/architecture agnostic. This +allows us to write portable SIMD code. + +Volk kernels are always defined with a 'generic' proto-kernel, which +is written in plain C. With the generic kernel, the kernel becomes +portable to any platform. Kernels are then extended by adding +proto-kernels for new platforms in which they are desired. + +A good example of a Volk kernel with multiple proto-kernels defined is +the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar +multiplication of a vector of floating point numbers (each item in the +vector is multiplied by the same value). This kernel has the following +proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.' + +\code + void volk_32f_s32f_multiply_32f_a_generic + void volk_32f_s32f_multiply_32f_a_sse + void volk_32f_s32f_multiply_32f_a_avx + void volk_32f_s32f_multiply_32f_a_orc +\endcode + +These proto-kernels means that on platforms with AVX support, Volk can +select this option or the SSE option, depending on which is faster. On +other platforms, the ORC SIMD compiler might provide a solution. If +all else fails, Volk can fall back on the generic proto-kernel, which +will always work. + +Just a note on ORC. ORC is a SIMD compiler library that uses a generic +assembly-like language for SIMD commands. Based on the available SIMD +architecture of a system, it will try and compile a good +solution. Tests show that the results of ORC proto-kernels are +generally better than the generic versions but often not as good as +the hand-tuned proto-kernels for a specific SIMD architecture. This +is, of course, to be expected, and ORC provides a nice intermediary +step to performance improvements until a specific hand-tuned +proto-kernel can be made for a given platform. + +See Volk on +gnuradio.org for details on the Volk naming scheme. + + +\section volk_alignment Setting and Using Memory Alignment Information + +For Volk to work as best as possible, we want to use memory-aligned +SIMD calls, which means we have to have some way of knowing and +controlling the alignment of the buffers passed to gr_block's work +function. We set the alignment requirement for SIMD aligned memory +calls with: + +\code + const int alignment_multiple = + volk_get_alignment() / output_item_size; + set_alignment(std::max(1,alignment_multiple)); +\endcode + +The Volk function 'volk_get_alignment' provides the alignment of the +the machine architecture. We then base the alignment on the number of +output items required to maintain the alignment, so we divide the +number of alignment bytes by the number of bytes in an output items +(sizeof(float), sizeof(gr_complex), etc.). This value is then set per +block with the 'set_alignment' function. + +Because the scheduler tries to optimize throughput, the number of +items available per call to work will change and depends on the +availability of the read and write buffers. This means that it +sometimes cannot produce a buffer that is properly memory +aligned. This is an inevitable consequence of the scheduler +system. Instead of requiring alignment, the scheduler enforces the +alignment as much as possible, and when a buffer becomes unaligned, +the scheduler will work to correct it as much as possible. If a +block's buffers are unaligned, then, the scheduler sets a flag to +indicate as much so that the block can then decide what best to +do. The next section discusses the use of the aligned/unaligned +information in a gr_block's work function. + + +\section volk_work Using Alignment Properties in Work() + +The buffers passed to work/general_work in a gr_block are not +guaranteed to be aligned, but they will mostly be aligned whenever +possible. When not aligned, the 'is_unaligned()' flag will be set. So +a block can know if its buffers are aligned and make the right +decisions. This looks like: + +\code +int +gr_some_block::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + if(is_unaligned()) { + // do something with unaligned data. This can either be a manual + // handling of the items or a call to an unaligned Volk function. + volk_32f_something_32f_u(out, in, noutput_items); + } + else { + // Buffers are aligned; can call the aligned Volk function. + volk_32f_something_32f_a(out, in, noutput_items); + } + + return noutput_items; +} +\endcode + + + +\section volk_tuning Tuning Volk Performance + +VOLK comes with a profiler that will build a config file for the best +SIMD architecture for your processor. Run volk_profile that is +installed into $PREFIX/bin. This program tests all known VOLK kernels +for each architecture supported by the processor. When finished, it +will write to $HOME/.volk/volk_config the best architecture for the +VOLK function. This file is read when using a function to know the +best version of the function to execute. + +\subsection volk_hand_tuning Hand-Tuning Performance + +If you know a particular architecture works best for your processor, +you can specify the particular architecture to use in the VOLK +preferences file: $HOME/.volk/volk_config + +The file looks like: + +\code + volk_ +\endcode + +Where the "FUNCTION_NAME" is the particular function that you want to +over-ride the default value and "ARCHITECTURE" is the VOLK SIMD +architecture to use (generic, sse, sse2, sse3, avx, etc.). For +example, the following config file tells VOLK to use SSE3 for the +aligned and unaligned versions of a function that multiplies two +complex streams together. + +\code + volk_32fc_x2_multiply_32fc_a sse3 + volk_32fc_x2_multiply_32fc_u sse3 +\endcode + +\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a +volk_config file that sets all architectures to 'generic' as a way to +test the vectorized versus non-vectorized implementations. + +*/ + + diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 68b098943..8f69a9737 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -14,7 +14,7 @@ the GNU Radio blog< \section build Building GNU Radio -See the \ref page_build page for details about the project's +See the \ref build_guide page for details about the project's dependencies and build process. diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox deleted file mode 100644 index 0e444ebba..000000000 --- a/docs/doxygen/other/volk_guide.dox +++ /dev/null @@ -1,161 +0,0 @@ -/*! \page volk_guide Instructions for using Volk in GNU Radio - -\section volk_intro Introduction - -Volk is the Vector-Optimized Library of Kernels. It is a library that -contains kernels of hand-written SIMD code for different mathematical -operations. Since each SIMD architecture can be greatly different and -no compiler has yet come along to handle vectorization properly or -highly efficiently, Volk approaches the problem differently. For each -architecture or platform that a developer wishes to vectorize for, a -new proto-kernel is added to Volk. At runtime, Volk will select the -correct proto-kernel. In this way, the users of Volk call a kernel for -performing the operation that is platform/architecture agnostic. This -allows us to write portable SIMD code. - -Volk kernels are always defined with a 'generic' proto-kernel, which -is written in plain C. With the generic kernel, the kernel becomes -portable to any platform. Kernels are then extended by adding -proto-kernels for new platforms in which they are desired. - -A good example of a Volk kernel with multiple proto-kernels defined is -the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar -multiplication of a vector of floating point numbers (each item in the -vector is multiplied by the same value). This kernel has the following -proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'orc.' - -\code - void volk_32f_s32f_multiply_32f_a_generic - void volk_32f_s32f_multiply_32f_a_sse - void volk_32f_s32f_multiply_32f_a_avx - void volk_32f_s32f_multiply_32f_a_orc -\endcode - -These proto-kernels means that on platforms with AVX support, Volk can -select this option or the SSE option, depending on which is faster. On -other platforms, the ORC SIMD compiler might provide a solution. If -all else fails, Volk can fall back on the generic proto-kernel, which -will always work. - -Just a note on ORC. ORC is a SIMD compiler library that uses a generic -assembly-like language for SIMD commands. Based on the available SIMD -architecture of a system, it will try and compile a good -solution. Tests show that the results of ORC proto-kernels are -generally better than the generic versions but often not as good as -the hand-tuned proto-kernels for a specific SIMD architecture. This -is, of course, to be expected, and ORC provides a nice intermediary -step to performance improvements until a specific hand-tuned -proto-kernel can be made for a given platform. - -See Volk on -gnuradio.org for details on the Volk naming scheme. - - -\section volk_alignment Setting and Using Memory Alignment Information - -For Volk to work as best as possible, we want to use memory-aligned -SIMD calls, which means we have to have some way of knowing and -controlling the alignment of the buffers passed to gr_block's work -function. We set the alignment requirement for SIMD aligned memory -calls with: - -\code - const int alignment_multiple = - volk_get_alignment() / output_item_size; - set_alignment(std::max(1,alignment_multiple)); -\endcode - -The Volk function 'volk_get_alignment' provides the alignment of the -the machine architecture. We then base the alignment on the number of -output items required to maintain the alignment, so we divide the -number of alignment bytes by the number of bytes in an output items -(sizeof(float), sizeof(gr_complex), etc.). This value is then set per -block with the 'set_alignment' function. - -Because the scheduler tries to optimize throughput, the number of -items available per call to work will change and depends on the -availability of the read and write buffers. This means that it -sometimes cannot produce a buffer that is properly memory -aligned. This is an inevitable consequence of the scheduler -system. Instead of requiring alignment, the scheduler enforces the -alignment as much as possible, and when a buffer becomes unaligned, -the scheduler will work to correct it as much as possible. If a -block's buffers are unaligned, then, the scheduler sets a flag to -indicate as much so that the block can then decide what best to -do. The next section discusses the use of the aligned/unaligned -information in a gr_block's work function. - - -\section volk_work Using Alignment Properties in Work() - -The buffers passed to work/general_work in a gr_block are not -guaranteed to be aligned, but they will mostly be aligned whenever -possible. When not aligned, the 'is_unaligned()' flag will be set. So -a block can know if its buffers are aligned and make the right -decisions. This looks like: - -\code -int -gr_some_block::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - if(is_unaligned()) { - // do something with unaligned data. This can either be a manual - // handling of the items or a call to an unaligned Volk function. - volk_32f_something_32f_u(out, in, noutput_items); - } - else { - // Buffers are aligned; can call the aligned Volk function. - volk_32f_something_32f_a(out, in, noutput_items); - } - - return noutput_items; -} -\endcode - - - -\section volk_tuning Tuning Volk Performance - -VOLK comes with a profiler that will build a config file for the best -SIMD architecture for your processor. Run volk_profile that is -installed into $PREFIX/bin. This program tests all known VOLK kernels -for each architecture supported by the processor. When finished, it -will write to $HOME/.volk/volk_config the best architecture for the -VOLK function. This file is read when using a function to know the -best version of the function to execute. - -\subsection volk_hand_tuning Hand-Tuning Performance - -If you know a particular architecture works best for your processor, -you can specify the particular architecture to use in the VOLK -preferences file: $HOME/.volk/volk_config - -The file looks like: - -\code - volk_ -\endcode - -Where the "FUNCTION_NAME" is the particular function that you want to -over-ride the default value and "ARCHITECTURE" is the VOLK SIMD -architecture to use (generic, sse, sse2, sse3, avx, etc.). For -example, the following config file tells VOLK to use SSE3 for the -aligned and unaligned versions of a function that multiplies two -complex streams together. - -\code - volk_32fc_x2_multiply_32fc_a sse3 - volk_32fc_x2_multiply_32fc_u sse3 -\endcode - -\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a -volk_config file that sets all architectures to 'generic' as a way to -test the vectorized versus non-vectorized implementations. - -*/ -- cgit From 5fcb7ebd473709fd9e4e99d542f21d3cee5aaf05 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 2 Oct 2012 13:08:11 -0400 Subject: docs: Adding notes discussing how to use new max_output_buffer feature. Also sneaking in a new analog group for gr-analog. --- docs/doxygen/other/group_defs.dox | 1 + docs/doxygen/other/main_page.dox | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index 213486b7a..4aee49ec8 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -28,6 +28,7 @@ /*! \defgroup slicedice_blk Slicing and Dicing Streams */ /*! \defgroup vocoder_blk Voice Encoders and Decoders */ /*! \defgroup digital Digital Modulation Blocks */ +/*! \defgroup analog Analog Communications Blocks */ /*! \defgroup qtgui_blk QT Graphical Interfaces */ /*! \defgroup uhd_blk UHD Interface */ /*! \defgroup audio_blk Audio Interface */ diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index c90ad883f..f2ab2a436 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -139,6 +139,56 @@ the FIR filter, which can receive up to 2000 items. tb.run(1000) \endcode +In some situations, you might actually want to restrict the size of +the buffer itself. This can help to prevent a buffer who is blocked +for data from just increasing the amount of items in its buffer, which +will then cause an increased latency for new samples. You can set the +size of an output buffer for each output port for every block. + +WARNING: This is an advanced feature in GNU Radio and should not be +used without a full understanding of this concept as explained below. + +To set the output buffer size of a block, you simply call: + +\code + tb.blk0.set_max_output_buffer(2000) + tb.blk1.set_max_output_buffer(2000,1) + tb.start() + print tb.blk1.max_output_buffer(0) + print tb.blk1.max_output_buffer(1) +\endcode + +In the above example, all ports of blk0 are set to a buffer size of +2000 in _items_ (not bytes), and blk1 only sets the size for output +port 1, any and all other ports use the default. The third and fourth +lines just print out the buffer sizes for ports 0 and 1 of blk1. This +is done after start() is called because the values are updated based +on what is actually allocated to the block's buffers. + +NOTES: + +1. Buffer length assignment is done once at runtime (i.e., when run() +or start() is called). So to set the max buffer lengths, the +set_max_output_buffer calls must be done before this. + +2. Once the flowgraph is started, the buffer lengths for a block are +set and cannot be dynamically changed, even during a +lock()/unlock(). If you need to change the buffer size, you will have +to delete the block and rebuild it, and therefore must disconnect and +reconnect the blocks. + +3. This can affect throughput. Large buffers are designed to improve +the efficiency and speed of the program at the expense of +latency. Limiting the size of the buffer may decrease performance. + +4. The real buffer size is actually based on a minimum granularity of +the system. Typically, this is a page size, which is typically 4096 +bytes. This means that any buffer size that is specified with this +command will get rounded up to the nearest granularity (e.g., page) +size. When calling max_output_buffer(port) after the flowgraph is +started, you will get how many items were actually allocated in the +buffer, which may be different than what was initially specified. + \section reconfigure Reconfiguring Flowgraphs -- cgit From 1e528816fd70f3a61d7f00a370cb056f03ceb6a7 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 2 Oct 2012 14:52:07 -0400 Subject: core: fixed swig file for exporting max/min buffer sizes with port first. --- docs/doxygen/other/main_page.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index f2ab2a436..282682464 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -152,7 +152,7 @@ To set the output buffer size of a block, you simply call: \code tb.blk0.set_max_output_buffer(2000) - tb.blk1.set_max_output_buffer(2000,1) + tb.blk1.set_max_output_buffer(1, 2000) tb.start() print tb.blk1.max_output_buffer(0) print tb.blk1.max_output_buffer(1) -- cgit From 996e5996d64f90c85da8681e7df3086e20bcb530 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 13 Dec 2012 18:09:49 -0500 Subject: docs: added a page detailing metadata format. --- docs/doxygen/other/metadata.dox | 322 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 docs/doxygen/other/metadata.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox new file mode 100644 index 000000000..5b20b9e73 --- /dev/null +++ b/docs/doxygen/other/metadata.dox @@ -0,0 +1,322 @@ +/*! \page page_metadata Metadata Information + +\section Introduction + +Metadata files have extra information in the form of headers that +carry metadata about the samples in the file. Raw, binary files carry +no extra information and must be handled delicately. Any changes in +the system state such as sample rate or if a receiver's frequency are +not conveyed with the data in the file itself. Header of metadata +solve this problem. + +We write metadata files using gr_file_meta_sink and read metadata +files using gr_file_meta_source. + +Metadata files have headers that carry information about a segment of +data within the file. The header structure is described in detail in +the next section. A metadata file always starts with a header that +describes the basic structure of the data. It contains information +about the data type, if it's complex, the sample rate of the segment, +the time stamp of the first sample of the segment, and information +regarding the header size and segment size. + +Headers have two main tags associated with them: + +- rx_rate: the sample rate of the stream. +- rx_time: the time stamp of the first item in the segment. + +These tags were inspired by the UHD tag format. + +The header gives enough information to process and handle the +data. One cautionary note, though, is that the data type should never +change within a file. There should be very little need for this, but +more importantly. GNU Radio blocks can only set the data type of their +IO signatures in the constructor, so changes in the data type +afterward will not be recognized. + +We also have an extra header segment that is option. This can be +loaded up at the beginning by the user specifying some extra metadata +that should be transmitted along with the data. It also grows whenever +it sees a stream tag, so the dictionary will contain and key:value +pairs out of tags from the flowgraph. + + +\subsection types Types of Metadata Files + +GNU Radio currently supports two types of metadata files: + +- inline: headers are inline with the data in the same file. +- detached: headers are in a separate header file from the data. + +The inline method is the standard version. When a detached header is +used, the headers are simply inserted back-to-back in the detached +header file. The dat file, then, is the standard raw binary format +with no interruptions in the data. + + +\subsection updating Updating Headers + +While there is always a header that starts a metadata file, they are +updated throughout as well. There are two events that trigger a new +header. We define a segment as the unit of data associated with the +last header. + +The first event that will trigger a new header is when enough samples +have been written for the given segment. This number is defined as the +maximum segment size and is a parameter we pass to the +file_meta_sink. It defaults to 1 million items (items, not +bytes). When that number of items is reached, a new header is +generated and a new segment is started. This makes it easier for us to +manipulate the data later and helps protect against catastrophic data +loss. + +The second event to trigger a new segment is if a new tag is +observed. If the tag is a standard tag in the header, the header value +is updated, the header and current extras are written to file, and the +segment begins again. If a tag from the extras is seen, the value +associated with that tag is updated; and if a new tag is seen, a new +key:value pair are added to the extras dictionary. + +When new tags are seen, we generate a new segment so that we make sure +that all samples in that segment are defined by the header. If the +sample rate changes, we create a new segment where all of the new +samples are at that new rate. Also, in the case of UHD devices, if a +segment loss is observed, it will generate a new timestamp as a tag of +'rx_time'. We create a new file segment that reflects this change to +keep the sample times exact. + + +\subsection implementation Implementation + +Metadata files are created using gr_file_meta_sink. The default +behavior is to create a single file with inline headers as +metadata. An option can be set to switch to detached header mode. + +Metadata file are read into a flowgraph using +gr_file_meta_source. This source reads a metadata file, inline by +default with a settable option to use detached headers. The data from +the segments is converted into a standard streaming output. The +'rx_rate' and 'rx_time' and all key:value pairs in the extra header +are converted into tags and added to the stream tags interface. + + +\section structure Structure + +The file metadata consists of a static mandatory header and a dynamic +optional extras header. Each header is a separate PMT +dictionary. Headers are created by building a PMT dictionary of +key:value pairs, then the dictionary is serialized into a string to be +written to file. The header is always the same length that is +predetermined by the version of the header (this must be known +already). The header will then indicate if there is an extra data to +be extracted as a separate serialized dictionary. + +To work with the PMTs for creating and extracting header information, +we use PMT operators. For example, we create a simplified version of +the header in C++ like this: + +\code + using namespace pmt; + const char METADATA_VERSION = 0x0; + pmt_t header; + header = pmt_make_dict(); + header = pmt_dict_add(header, mp("version"), mp(METADATA_VERSION)); + header = pmt_dict_add(header, mp("rx_rate"), mp(samp_rate)); + std::string hdr_str = pmt_serialize_str(header); +\endcode + +The call to pmt_dict_add adds a new key:value pair to the +dictionary. Notice that it both takes and returns the 'header' +variable. This is because we are actually creating a new dictionary +with this function, so we just assign it to the same variable. + +The 'mp' functions are convenience functions provided by the PMT +library. They interpret the data type of the value being inserted and +call the correct 'pmt_from_xxx' function. For more direct control over +the data type, see PMT functions in pmt.h, such as pmt_from_uint64 or +pmt_from_double. + +We finish this off by using 'pmt_serialize_str' to convert the PMT +dictionary into a specialized string format that makes it easy to +write to a file. + +The header is always METADATA_HEADER_SIZE bytes long and a metadata +file always starts with a header. So to extract the header from a +file, we need to read in this many bytes from the beginning of the +file and deserialize it. An important note about this is that the +deserialize function must operate on a std::string. The serialized +format of a dictionary contains null characters, so normal C character +arrays (e.g., 'char *s') get confused. + +Assuming that 'std::string str' contains the full string as read from +a file, we can access the dictionary in C++ like this: + +\code + pmt_t hdr = pmt_deserialize_str(str); + if(pmt_dict_has_key(hdr, pmt_string_to_symbol("strt"))) { + pmt_t r = pmt_dict_ref(hdr, pmt_string_to_symbol("strt"), PMT_NIL); + uint64_t seg_start = pmt_to_uint64(r); + uint64_t extra_len = seg_start - METADATA_HEADER_SIZE; + } +\endcode + +This example first deserializes the string into a PMT dictionary +again. This will throw an error if the string is malformed and cannot +be deserialized correctly. We then want to get access to the item with +key 'strt'. As the next subsection will show, this value indicates at +which byte the data segment starts. We first check to make sure that +this key exists in the dictionary. If not, our header does not contain +the correct information and we might want to handle this as an error. + +Assuming the header is properly formatted, we then get the particular +item referenced by the key 'strt'. This is a uint64_t, so we use the +PMT function to extract and convert this value properly. We now know +if we have an extra header in the file by looking at the difference +between 'seg_start' and the static header size, +METADATA_HEADER_SIZE. If the 'extra_len' is greater than 0, we know we +have an extra header that we can process. Moreover, this also tells us +the size of the serialized PMT dictionary in bytes, so we can easily +read this many bytes from the file. We can then deserialize and parse +this header just like the first. + + +\subsection header Header Information + +The header is a PMT dictionary with a known structure. This structure +may change, but we version the headers, so all headers of version X +must be the same length and structure. As of now, we only have version +0 headers, which look like the following: + +- version: (char) version number (usually set to METADATA_VERSION) +- rx_rate: (double) Stream's sample rate +- rx_time: (pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) +- type: (int) data type (enum below) +- cplx: (bool) true if data is complex +- strt: (uint64_t) start of data relative to current header +- size: (uint64_t) size of following data segment + +The data types are indicated by an integer value from the following +enumeration type: + +\code +enum gr_file_types { + GR_FILE_BYTE=0, + GR_FILE_CHAR=0, + GR_FILE_SHORT=1, + GR_FILE_INT, + GR_FILE_LONG, + GR_FILE_LONG_LONG, + GR_FILE_FLOAT, + GR_FILE_DOUBLE, +}; +\endcode + +\subsection extras Extras Information + +The extras section is an optional segment of the header. If 'strt' == +METADATA_HEADER_SIZE, then there is no extras. Otherwise, it is simply +a PMT dictionary of key:value pairs. The extras header can contain +anything and can grow while a program is running. + +We can insert extra data into the header at the beginning if we +wish. All we need to do is use the 'pmt_dict_add' function to insert +our hand-made metadata. This can be useful to add our own markers and +information. + +The main role of the extras header, though, is as a container to hold +any stream tags. When a stream tag is observed coming in, the tag's +key and value are added to the dictionary. Like a standard dictionary, +any time a key already exists, the value will be updated. If the key +does not exist, a new entry is created and the new key:value pair are +added together. So any new tags that the file metadata sink sees will +add to the dictionary. It is therefore important to always check the +'strt' value of the header to see if the length of the extras +dictionary has changed at all. + +When reading out data from the extras, we do not necessarily know the +data type of the PMT value. The key is always a PMT symbol, but the +value can be any other PMT type. There are PMT functions that allow us +to query the PMT to test if it is a particular type. We also have the +ability to do 'pmt_print' on any PMT object to print it to +screen. Before converting from a PMT to it's natural data type, it is +necessary to know the data type. + + +\section Utilities + +GNU Radio comes with a couple of utilities to help in debugging and +manipulating metadata files. There is a general parser in Python that +will convert the PMT header and extra header into Python +dictionaries. This utility is: + +- gnuradio-core/src/python/gnuradio/parse_file_metadata.py + +This program is installed into the Python directory under the +'gnuradio' module, so it can be accessed with: + +\code +from gnuradio import parse_file_metadata +\endcode + +It defines HEADER_LENGTH as the static length of the metadata header +size. It also has dictionaries that can be used to convert from the +file type to a string (ftype_to_string) and one to convert from the +file type to the size of the data type in bytes (ftype_to_size). + +The 'parse_header' takes in a PMT dictionary, parses it, and returns a +Python dictionary. An optional 'VERBOSE' bool can be set to print the +information to standard out. + +The 'parse_extra_dict' is similar in that it converts from a PMT +dictionary to a Python dictionary. The values are kept in their PMT +format since we do not necessarily know the native data type. + +A program called 'gr_read_file_metadata' is installed into the path +and can be used to read out all header information from a metadata +file. This program is just called with the file name as the first +command-line argument. An option '-D' will handle detached header +files where the file of headers is expected to be the file name of the +data with '.hdr' appended to it. + + +\section Examples + +Examples are located in: + +- gnuradio-core/src/examples/metadata + +Currently, there are two GRC example programs. + +- file_metadata_sink: create a metadata file from UHD samples. +- file_metadata_source: read the metadata file as input to a simple graph. + +The file sink example can be switched to use a signal source instead +of a UHD source, but no extra tagged data is used in this mode. + +The file source example pushes the data stream to a new raw file while +a tag debugger block prints out any tags observed in the metedata +file. A QT GUI time sink is used to look at the signal as well. + +The following shows a simple way of creating extra metadata for a +metadata file. This example is just showing how we can insert a date +into the metadata to keep track of later. The date in this case is +encoded as day|month|year. + +\code + from gruel import pmt + + key = pmt.pmt_intern("date") + val = pmt.pmt_from_uint64(13122012) + + extras = pmt.pmt_make_dict() + extras = pmt.pmt_dict_add(extras, key, val) + extras_str = pmt.pmt_serialize_str(extrasa) + self.sink = gr.file_meta_sink(gr.sizeof_gr_complex, + "/tmp/metadat_file.out", + samp_rate, 1, + gr.GR_FILE_FLOAT, True, + 1000000, extra_str, False) + +\endcode + +*/ -- cgit From 3910c6da3c62232e6593e5fcfe53f5ece933a294 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 14 Dec 2012 13:57:29 -0500 Subject: core: adding itemsize key to metadata header to allow for vectorized items. This also simplifies some code in the source since we're told exactly what the items size is and don't have to infer. Also adds an example using vector items. --- docs/doxygen/other/metadata.dox | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index 5b20b9e73..4bc310531 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -16,9 +16,9 @@ Metadata files have headers that carry information about a segment of data within the file. The header structure is described in detail in the next section. A metadata file always starts with a header that describes the basic structure of the data. It contains information -about the data type, if it's complex, the sample rate of the segment, -the time stamp of the first sample of the segment, and information -regarding the header size and segment size. +about the item size, data type, if it's complex, the sample rate of +the segment, the time stamp of the first sample of the segment, and +information regarding the header size and segment size. Headers have two main tags associated with them: @@ -190,10 +190,11 @@ must be the same length and structure. As of now, we only have version - version: (char) version number (usually set to METADATA_VERSION) - rx_rate: (double) Stream's sample rate - rx_time: (pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) +- size: (int) item size in bytes - reflects vector length if any. - type: (int) data type (enum below) - cplx: (bool) true if data is complex - strt: (uint64_t) start of data relative to current header -- size: (uint64_t) size of following data segment +- bytes: (uint64_t) size of following data segment in bytes The data types are indicated by an integer value from the following enumeration type: -- cgit From 8e8ed231cd2469e1a39c5ae6af23ac9b29264af7 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 14 Dec 2012 16:00:27 -0500 Subject: gruel: Enabling serialize/deserialize for PMT vectors. --- docs/doxygen/other/metadata.dox | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index 4bc310531..1b3c891a8 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -301,17 +301,17 @@ file. A QT GUI time sink is used to look at the signal as well. The following shows a simple way of creating extra metadata for a metadata file. This example is just showing how we can insert a date into the metadata to keep track of later. The date in this case is -encoded as day|month|year. +encoded as a vector of uint16 with [day, month, year]. \code from gruel import pmt key = pmt.pmt_intern("date") - val = pmt.pmt_from_uint64(13122012) + val = pmt.pmt_init_u16vector(3, [13,12,2012]) extras = pmt.pmt_make_dict() extras = pmt.pmt_dict_add(extras, key, val) - extras_str = pmt.pmt_serialize_str(extrasa) + extras_str = pmt.pmt_serialize_str(extras) self.sink = gr.file_meta_sink(gr.sizeof_gr_complex, "/tmp/metadat_file.out", samp_rate, 1, -- cgit From 461ece56b36a44b2405282630157739c7f9a26ba Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 14 Dec 2012 16:10:30 -0500 Subject: blocks: moving file metadata sink/source to gr-blocks. --- docs/doxygen/other/metadata.dox | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index 1b3c891a8..9fad7c584 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -9,8 +9,8 @@ the system state such as sample rate or if a receiver's frequency are not conveyed with the data in the file itself. Header of metadata solve this problem. -We write metadata files using gr_file_meta_sink and read metadata -files using gr_file_meta_source. +We write metadata files using blocks::file_meta_sink and read metadata +files using blocks::file_meta_source. Metadata files have headers that carry information about a segment of data within the file. The header structure is described in detail in @@ -88,12 +88,12 @@ keep the sample times exact. \subsection implementation Implementation -Metadata files are created using gr_file_meta_sink. The default +Metadata files are created using file_meta_sink. The default behavior is to create a single file with inline headers as metadata. An option can be set to switch to detached header mode. Metadata file are read into a flowgraph using -gr_file_meta_source. This source reads a metadata file, inline by +file_meta_source. This source reads a metadata file, inline by default with a settable option to use detached headers. The data from the segments is converted into a standard streaming output. The 'rx_rate' and 'rx_time' and all key:value pairs in the extra header @@ -250,13 +250,13 @@ manipulating metadata files. There is a general parser in Python that will convert the PMT header and extra header into Python dictionaries. This utility is: -- gnuradio-core/src/python/gnuradio/parse_file_metadata.py +- gr-blocks/python/parse_file_metadata.py This program is installed into the Python directory under the 'gnuradio' module, so it can be accessed with: \code -from gnuradio import parse_file_metadata +from gnuradio.blocks import parse_file_metadata \endcode It defines HEADER_LENGTH as the static length of the metadata header @@ -284,12 +284,14 @@ data with '.hdr' appended to it. Examples are located in: -- gnuradio-core/src/examples/metadata +- gr-blocks/examples/metadata -Currently, there are two GRC example programs. +Currently, there are a few GRC example programs. - file_metadata_sink: create a metadata file from UHD samples. - file_metadata_source: read the metadata file as input to a simple graph. +- file_metadata_vector_sink: create a metadata file from UHD samples. +- file_metadata_vector_source: read the metadata file as input to a simple graph. The file sink example can be switched to use a signal source instead of a UHD source, but no extra tagged data is used in this mode. @@ -298,6 +300,9 @@ The file source example pushes the data stream to a new raw file while a tag debugger block prints out any tags observed in the metedata file. A QT GUI time sink is used to look at the signal as well. +The versions with 'vector' in the name are similar except they use +vectors of data. + The following shows a simple way of creating extra metadata for a metadata file. This example is just showing how we can insert a date into the metadata to keep track of later. The date in this case is @@ -305,6 +310,7 @@ encoded as a vector of uint16 with [day, month, year]. \code from gruel import pmt + from gnuradio import blocks key = pmt.pmt_intern("date") val = pmt.pmt_init_u16vector(3, [13,12,2012]) @@ -312,11 +318,11 @@ encoded as a vector of uint16 with [day, month, year]. extras = pmt.pmt_make_dict() extras = pmt.pmt_dict_add(extras, key, val) extras_str = pmt.pmt_serialize_str(extras) - self.sink = gr.file_meta_sink(gr.sizeof_gr_complex, - "/tmp/metadat_file.out", - samp_rate, 1, - gr.GR_FILE_FLOAT, True, - 1000000, extra_str, False) + self.sink = blocks.file_meta_sink(gr.sizeof_gr_complex, + "/tmp/metadat_file.out", + samp_rate, 1, + blocks.GR_FILE_FLOAT, True, + 1000000, extra_str, False) \endcode -- cgit From c866b5ea38dbabcfa08ae3e9989ad5ddfbebfbbe Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 17 Dec 2012 11:02:58 -0500 Subject: docs: using full namspace for references in metadata.dox for proper linking. --- docs/doxygen/other/metadata.dox | 45 +++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index 9fad7c584..f867a06f2 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -9,8 +9,8 @@ the system state such as sample rate or if a receiver's frequency are not conveyed with the data in the file itself. Header of metadata solve this problem. -We write metadata files using blocks::file_meta_sink and read metadata -files using blocks::file_meta_source. +We write metadata files using gr::blocks::file_meta_sink and read metadata +files using gr::blocks::file_meta_source. Metadata files have headers that carry information about a segment of data within the file. The header structure is described in detail in @@ -88,28 +88,29 @@ keep the sample times exact. \subsection implementation Implementation -Metadata files are created using file_meta_sink. The default -behavior is to create a single file with inline headers as +Metadata files are created using gr::blocks::file_meta_sink. The +default behavior is to create a single file with inline headers as metadata. An option can be set to switch to detached header mode. Metadata file are read into a flowgraph using -file_meta_source. This source reads a metadata file, inline by -default with a settable option to use detached headers. The data from -the segments is converted into a standard streaming output. The -'rx_rate' and 'rx_time' and all key:value pairs in the extra header -are converted into tags and added to the stream tags interface. +gr::blocks::file_meta_source. This source reads a metadata file, +inline by default with a settable option to use detached headers. The +data from the segments is converted into a standard streaming +output. The 'rx_rate' and 'rx_time' and all key:value pairs in the +extra header are converted into tags and added to the stream tags +interface. \section structure Structure The file metadata consists of a static mandatory header and a dynamic optional extras header. Each header is a separate PMT -dictionary. Headers are created by building a PMT dictionary of -key:value pairs, then the dictionary is serialized into a string to be -written to file. The header is always the same length that is -predetermined by the version of the header (this must be known -already). The header will then indicate if there is an extra data to -be extracted as a separate serialized dictionary. +dictionary. Headers are created by building a PMT dictionary +(pmt::pmt_make_dict) of key:value pairs, then the dictionary is +serialized into a string to be written to file. The header is always +the same length that is predetermined by the version of the header +(this must be known already). The header will then indicate if there +is an extra data to be extracted as a separate serialized dictionary. To work with the PMTs for creating and extracting header information, we use PMT operators. For example, we create a simplified version of @@ -125,7 +126,7 @@ the header in C++ like this: std::string hdr_str = pmt_serialize_str(header); \endcode -The call to pmt_dict_add adds a new key:value pair to the +The call to pmt::pmt_dict_add adds a new key:value pair to the dictionary. Notice that it both takes and returns the 'header' variable. This is because we are actually creating a new dictionary with this function, so we just assign it to the same variable. @@ -133,10 +134,10 @@ with this function, so we just assign it to the same variable. The 'mp' functions are convenience functions provided by the PMT library. They interpret the data type of the value being inserted and call the correct 'pmt_from_xxx' function. For more direct control over -the data type, see PMT functions in pmt.h, such as pmt_from_uint64 or -pmt_from_double. +the data type, see PMT functions in pmt.h, such as +pmt::pmt_from_uint64 or pmt::pmt_from_double. -We finish this off by using 'pmt_serialize_str' to convert the PMT +We finish this off by using pmt::pmt_serialize_str to convert the PMT dictionary into a specialized string format that makes it easy to write to a file. @@ -189,7 +190,7 @@ must be the same length and structure. As of now, we only have version - version: (char) version number (usually set to METADATA_VERSION) - rx_rate: (double) Stream's sample rate -- rx_time: (pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) +- rx_time: (pmt::pmt_t pair - (uint64_t, double)) Time stamp (format from UHD) - size: (int) item size in bytes - reflects vector length if any. - type: (int) data type (enum below) - cplx: (bool) true if data is complex @@ -220,7 +221,7 @@ a PMT dictionary of key:value pairs. The extras header can contain anything and can grow while a program is running. We can insert extra data into the header at the beginning if we -wish. All we need to do is use the 'pmt_dict_add' function to insert +wish. All we need to do is use the pmt::pmt_dict_add function to insert our hand-made metadata. This can be useful to add our own markers and information. @@ -238,7 +239,7 @@ When reading out data from the extras, we do not necessarily know the data type of the PMT value. The key is always a PMT symbol, but the value can be any other PMT type. There are PMT functions that allow us to query the PMT to test if it is a particular type. We also have the -ability to do 'pmt_print' on any PMT object to print it to +ability to do pmt::pmt_print on any PMT object to print it to screen. Before converting from a PMT to it's natural data type, it is necessary to know the data type. -- cgit From a21c5f703a2030b4109811ccf3bcb2906df5d466 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 18 Dec 2012 13:36:17 -0500 Subject: docs: Adding a page describing the message passing interface. --- docs/doxygen/other/msg_passing.dox | 266 +++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 docs/doxygen/other/msg_passing.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox new file mode 100644 index 000000000..564a71c4a --- /dev/null +++ b/docs/doxygen/other/msg_passing.dox @@ -0,0 +1,266 @@ +/*! \page page_msg_passing Message Passing + +\section intro Introduction + +GNU Radio was originally a streaming system with no other mechanism to +pass data between blocks. Streams of data are a model that work well +for samples, bits, etc., but are not really the right mechanism for +control data, metadata, and, often, packet structures (at least at +some point in the processing chain). + +We solved part of this problem a few years ago by introducing the tag +stream. This is a parallel stream to the data streaming. The +difference is that tags are designed to hold metadata and control +information. Tags are specifically associated with a particular sample +in the data stream and flow downstream alongside the data. This model +allows other blocks to identify that an event or action has occurred +or should occur on a particular item. The major limitation is that the +tag stream is really only accessible inside a work function and only +flows in one direction. Its benefit is that it is isosynchronous with +the data. + +We want a more general message passing system for a couple of +reasons. The first is to allow blocks downstream to communicate back +to blocks upstream. The second is to allow an easier way for us to +communicate back and forth between external applications and GNU +Radio. The new message passing interface handles these cases, although +it does so on an asynchronous basis. + + +\section api Message Passing API + +The message passing interface is designed into the gr_basic_block, +which is the parent class for all blocks in GNU Radio. Each block has +a set of message queues to hold incoming messages and can post +messages to the message queues of other blocks. The blocks also +distinguish between input and output ports. + +A block has to declare its input and output message ports in its +constructor. The message ports are described by a name, which is in +practice a PMT symbol (i.e., an interned string). The API calls +to register a new port are: + +\code + void message_port_register_in(pmt::pmt_t port_id) + void message_port_register_out(pmt::pmt_t port_id) +\endcode + +The ports are now identifiable by that port name. Other blocks who may +want to post or receive messages on a port must subscribe to it. When +a block has a message to send, they are published on a particular +port. The subscribe and publish API looks like: + +\code + void message_port_pub(pmt::pmt_t port_id, + pmt::pmt_t msg); + void message_port_sub(pmt::pmt_t port_id, + pmt::pmt_t target); + void message_port_unsub(pmt::pmt_t port_id, + pmt::pmt_t target); +\endcode + +Any block that has a subscription to another block's output message +port will receive the message when it is published. Internally, when a +block publishes a message, it simply iterates through all blocks that +have subscribed and uses the gr_basic_block::_post method to send the +message to that block's message queue. + +From the flowgraph level, we have instrumented a gr_hier_block2::msg_connect +method to make it easy to subscribe blocks to other blocks' +messages. The message connection method looks like the following +code. Assume that the block \b src has an output message port named +\a pdus and the block \b dbg has an input port named \a print. + +\code + self.tb.msg_connect(src, "pdus", dbg, "print") +\endcode + +All messages published by the \b src block on port \a pdus will be +received by \b dbg on port \a print. Note here how we are just using +strings to define the ports, not PMT symbols. This is a convenience to +the user to be able to more easily type in the port names (for +reference, you can create a PMT symbol in Python using the +pmt::pmt_intern function as pmt.pmt_intern("string")). + +Users can also query blocks for the names of their input and output +ports using the following API calls: + +\code + pmt::pmt_t message_ports_in(); + pmt::pmt_t message_ports_out(); +\endcode + +The return value for these are a PMT vector filled with PMT symbols, +so PMT operators must be used to manipulate them. + +Each block has internal methods to handle posting and receiving of +messages. The gr_basic_block::_post method takes in a message and +places it into its queue. The publishing model uses the +gr_basic_block::_post method of the blocks as the way to access the +message queue. So the message queue of the right name will have a new +message. Posting messages also has the benefit of waking up the +block's thread if it is in a wait state. So if idle, as soon as a +message is posted, it will wake up and and call the message handler. + +The other side of the action in a block is in the message +handler. When a block has an input message port, it needs a callback +function to handle messages received on that port. We use a Boost bind +operator to bind the message port to the message handling +function. When a new message is pushed onto a port's message queue, +it is this function that is used to process the message. + + +\section examples Code Examples + +The following is snippets of code from blocks current in GNU Radio +that take advantage of message passing. We will be using +gr_message_debug and gr_tagged_stream_to_pdu below to show setting up +both input and output message passing capabilities. + +The gr_message_debug block is used for debugging the message passing +system. It describes two input message ports: \a print and \a +store. The \a print port simply prints out all messages to standard +out while the \a store port keeps a list of all messages posted to +it. This latter port works in conjunction with a +gr_message_debug::get_message(int i) call that allows us to retrieve +message \p i afterward. + +The constructor of this block looks like this: + +\code +{ + message_port_register_in(pmt::mp("print")); + set_msg_handler(pmt::mp("print"), + boost::bind(&gr_message_debug::print, this, _1)); + + message_port_register_in(pmt::mp("store")); + set_msg_handler(pmt::mp("store"), + boost::bind(&gr_message_debug::store, this, _1)); +} +\endcode + +So the two ports are registered by their respective names. We then use +the gr_basic_block::set_msg_handler function to identify this +particular port name with a callback function. The Boost \a bind +function (Boost::bind) +here binds the callback to a function of this block's class. So now +the block's gr_message_debug::print and gr_message_debug::store +functions are assigned to handle messages passed to them. Below is the +\a print function for reference. + +\code +void +gr_message_debug::print(pmt::pmt_t msg) +{ + std::cout << "***** MESSAGE DEBUG PRINT ********\n"; + pmt::pmt_print(msg); + std::cout << "**********************************\n"; +} +\endcode + +The function simply takes in the PMT message and prints it. The method +pmt::pmt_print is a function in the PMT library to print the +PMT in a friendly, (mostly) pretty manner. + +The gr_tagged_stream_to_pdu block only defines a single +output message port. In this case, its constructor looks like: + +\code +{ + message_port_register_out(pdu_port_id); +} +\endcode + +So we are only creating a single output port where \a pdu_port_id +is defined in the file gr_pdu.h as \a pdus. + +This blocks purpose is to take in a stream of samples along with +stream tags and construct a predefined PDU message from this. In GNU +Radio, we define a PDU as a PMT pair of (metadata, data). The metadata +describes the samples found in the data portion of the +pair. Specifically, the metadata can contain the length of the data +segment and any other information (sample rate, etc.). The PMT vectors +know their own length, so the length value is not actually necessary +unless useful for purposes down the line. The metadata is a PMT +dictionary while the data segment is a PMT uniform vector of either +bytes, floats, or complex values. + +In the end, when a PDU message is ready, the block calls its +gr_tagged_stream_to_pdu::send_message function that is shown below. + +\code +void +gr_tagged_stream_to_pdu::send_meassage() +{ + if(pmt::pmt_length(d_pdu_vector) != d_pdu_length) { + throw std::runtime_error("msg length not correct"); + } + + pmt::pmt_t msg = pmt::pmt_cons(d_pdu_meta, + d_pdu_vector); + message_port_pub(pdu_port_id, msg); + + d_pdu_meta = pmt::PMT_NIL; + d_pdu_vector = pmt::PMT_NIL; + d_pdu_length = 0; + d_pdu_remain = 0; + d_inpdu = false; +} +\endcode + +This function does a bit of checking to make sure the PDU is ok as +well as some cleanup in the end. But it is the line where the message +is published that is important to this discussion. Here, the block +posts the PDU message to any subscribers by calling +gr_basic_block::message_port_pub publishing method. + +There is similarly a gr_pdu_to_tagged_stream block that essentially +does the opposite. It acts as a source to a flowgraph and waits for +PDU messages to be posted to it on its input port \a pdus. It extracts +the metadata and data and processes them. The metadata dictionary is +split up into key:value pairs and stream tags are created out of +them. The data is then converted into an output stream of items and +passed along. The next section describes how PDUs can be passed into a +flowgraph using the gr_pdu_to_tagged_stream block. + +\section posting Posting from External Sources + +The last feature of the message passing architecture to discuss here +is how it can be used to take in messages from an external source. We +can call a block's gr_basic_block::_post method directly and pass it a +message. So any block with an input message port can receive messages +from the outside in this way. + +The following example uses a gr_pdu_to_tagged_stream block +as the source block to a flowgraph. Its purpose is to wait for +messages as PDUs posted to it and convert them to a normal stream. The +payload will be sent on as a normal stream while the meta data will be +decoded into tags and sent on the tagged stream. + +So if we have created a \b src block as a PDU to stream, it has a \a +pdus input port, which is how we will inject PDU messages to the +flowgraph. These PDUs could come from another block or flowgraph, but +here, we will create and insert them by hand. + +\code + port = pmt.pmt_intern("pdus") + msg = pmt.pmt_cons(pmt.PMT_NIL, + pmt.pmt_make_u8vector(16, 0xFF)) + src.to_basic_block()._post(port, msg) +\endcode + +The PDU's metadata section is empty, hence the pmt::PMT_NIL +object. The payload is now just a simple vector of 16 bytes of all +1's. To post the message, we have to access the block's gr_basic_block +class, which we do using the gr_basic_block::to_basic_block method and +then call the gr_basic_block::_post method to pass the PDU to the +right port. + +All of these mechanisms are explored and tested in the QA code of the +file qa_pdu.py. + +There are some examples of using the message passing infrastructure +through GRC in gnuradio-core/src/examples/msg_passing. + +*/ -- cgit From 77ea309277382d198681476976bd353a2a98e908 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 18 Dec 2012 15:30:58 -0500 Subject: docs: added a doxygen manual page describing PMT types and how to use them. --- docs/doxygen/other/pmt.dox | 348 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 docs/doxygen/other/pmt.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/pmt.dox b/docs/doxygen/other/pmt.dox new file mode 100644 index 000000000..61b73bca1 --- /dev/null +++ b/docs/doxygen/other/pmt.dox @@ -0,0 +1,348 @@ +/*! \page page_pmt Polymorphic Types + +\section intro Introduction + +Polymorphic Types are opaque data types that are designed as generic +containers of data that can be safely passed around between blocks and +threads in GNU Radio. They are heavily used in the stream tags and +message passing interfaces. The most complete list of PMT function is, +of course, the source code, specifically the header file pmt.h. This +manual page summarizes the most important features and points of PMTs. + + +\section datatype PMT Data Type + +All PMTs are of the type pmt::pmt_t. This is an opaque container and +PMT functions must be used to manipulate and even do things like +compare PMTs. PMTs are also \a immutable (except PMT vectors). We +never change the data in a PMT; instead, we create a new PMT with the +new data. The main reason for this is thread safety. We can pass PMTs +as tags and messages between blocks and each receives its own copy +that we can read from. However, we can never write to this object, and +so if multiple blocks have a reference to the same PMT, there is no +possibility of thread-safety issues of one reading the PMT data while +another is writing the data. If a block is trying to write new data to +a PMT, it actually creates a new PMT to put the data into. Thus we +allow easy access to data in the PMT format without worrying about +mutex locking and unlocking while manipulating them. + +PMTs can represent the following: + +- Boolean values of true/false +- Strings (as symbols) +- Integers (long and uint64) +- Floats (as doubles) +- Complex (as two doubles) +- Pairs +- Tuples +- Vectors (of PMTs) +- Uniform vectors (of any standard data type) +- Dictionaries (list of key:value pairs) +- Any (contains a boost::any pointer to hold anything) + +The PMT library also defines a set of functions that operate directly +on PMTs such as: + +- Equal/equivalence between PMTs +- Length (of a tuple or vector) +- Map (apply a function to all elements in the PMT) +- Reverse +- Get a PMT at a position in a list +- Serialize and deserialize +- Printing + +The constants in the PMT library are: + +- pmt::PMT_T - a PMT True +- pmt::PMT_F - a PMT False +- pmt::PMT_NIL - an empty PMT (think Python's 'None') + +\section insert Inserting and Extracting Data + +Use pmt.h for a complete guide to the list of functions used to create +PMTs and get the data from a PMT. When using these functions, remember +that while PMTs are opaque and designed to hold any data, the data +underneath is still a C++ typed object, and so the right type of +set/get function must be used for the data type. + +Typically, a PMT object can be made from a scalar item using a call +like "pmt::pmt_from_". Similarly, when getting data out of a +PMT, we use a call like "pmt::pmt_to_". For example: + +\code +double a = 1.2345; +pmt::pmt_t pmt_a = pmt::pmt_from_double(a); +double b = pmt::pmt_to_double(pmt_a); + +int c = 12345; +pmt::pmt_t pmt_c = pmt::pmt_from_long(c); +int d = pmt::pmt_to_long(pmt_c); +\endcode + +As a side-note, making a PMT from a complex number is not obvious: + +\code +std::complex a(1.2, 3.4); +pmt::pmt_t pmt_a = pmt::pmt_make_rectangular(a.real(), b.imag()); +std::complex b = pmt::pmt_to_complex(pmt_a); +\endcode + +Pairs, dictionaries, and vectors have different constructors and ways +to manipulate them, and these are explained in their own sections. + + +\section strings Strings + +PMTs have a way of representing short strings. These strings are +actually stored as interned symbols in a hash table, so in other +words, only one PMT object for a given string exists. If creating a +new symbol from a string, if that string already exists in the hash +table, the constructor will return a reference to the existing PMT. + +We create strings with the following functions, where the second +function, pmt::pmt_intern, is simply an alias of the first. + +\code +pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string")); +pmt::pmt_t str1 = pmt::pmt_intern(std::string("some string")); +\endcode + +The string can be retrieved using the inverse function: + +\code +std::string s = pmt::pmt_symbol_to_string(str0); +\endcode + + +\section tests Tests and Comparisons + +The PMT library comes with a number of functions to test and compare +PMT objects. In general, for any PMT data type, there is an equivalent +"pmt::pmt_is_". We can use these to test the PMT before trying +to access the data inside. Expanding our examples above, we have: + +\code +pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string")); +if(pmt::pmt_is_symbol(str0)) + std::string s = pmt::pmt_symbol_to_string(str0); + +double a = 1.2345; +pmt::pmt_t pmt_a = pmt::pmt_from_double(a); +if(pmt::pmt_is_double(pmt_a)) + double b = pmt::pmt_to_double(pmt_a); + +int c = 12345; +pmt::pmt_t pmt_c = pmt::pmt_from_long(c); +if(pmt::pmt_is_long(pmt_a)) + int d = pmt::pmt_to_long(pmt_c); + +\\ This will fail the test. Otherwise, trying to coerce \b pmt_c as a +\\ double when internally it is a long will result in an exception. +if(pmt::pmt_is_double(pmt_a)) + double d = pmt::pmt_to_double(pmt_c); + +\endcode + + +\section dict Dictionaries + +PMT dictionaries and lists of key:value pairs. They have a +well-defined interface for creating, adding, removing, and accessing +items in the dictionary. Note that every operation that changes the +dictionary both takes a PMT dictionary as an argument and returns a +PMT dictionary. The dictionary used as an input is not changed and the +returned dictionary is a new PMT with the changes made there. + +The following is a list of PMT dictionary functions. Click through to +get more information on what each does. + +- bool pmt::pmt_is_dict(const pmt_t &obj) +- pmt_t pmt::pmt_make_dict() +- pmt_t pmt::pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value) +- pmt_t pmt::pmt_dict_delete(const pmt_t &dict, const pmt_t &key) +- bool pmt::pmt_dict_has_key(const pmt_t &dict, const pmt_t &key) +- pmt_t pmt::pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t ¬_found) +- pmt_t pmt::pmt_dict_items(pmt_t dict) +- pmt_t pmt::pmt_dict_keys(pmt_t dict) +- pmt_t pmt::pmt_dict_values(pmt_t dict) + +This example does some basic manipulations of PMT dictionaries in +Python. Notice that we pass the dictionary \a a and return the results +to \a a. This still creates a new dictionary and removes the local +reference to the old dictionary. This just keeps our number of +variables small. + +\code +from gruel import pmt + +key0 = pmt.pmt_intern("int") +val0 = pmt.pmt_from_long(123) +val1 = pmt.pmt_from_long(234) + +key1 = pmt.pmt_intern("double") +val2 = pmt.pmt_from_double(5.4321) + +# Make an empty dictionary +a = pmt.pmt_make_dict() + +# Add a key:value pair to the dictionary +a = pmt.pmt_dict_add(a, key0, val0) +pmt.pmt_print(a) + +# Add a new value to the same key; +# new dict will still have one item with new value +a = pmt.pmt_dict_add(a, key0, val1) +pmt.pmt_print(a) + +# Add a new key:value pair +a = pmt.pmt_dict_add(a, key1, val2) +pmt.pmt_print(a) + +# Test if we have a key, then delete it +print pmt.pmt_dict_has_key(a, key1) +a = pmt.pmt_dict_delete(a, key1) +print pmt.pmt_dict_has_key(a, key1) + +ref = pmt.pmt_dict_ref(a, key0, pmt.PMT_NIL) +pmt.pmt_print(ref) + +# The following should never print +if(pmt.pmt_dict_has_key(a, key0) and pmt.pmt_eq(ref, pmt.PMT_NIL)): + print "Trouble! We have key0, but it returned PMT_NIL" +\endcode + +\section vectors Vectors + +PMT vectors come in two forms: vectors of PMTs and vectors of uniform +data. The standard PMT vector is a vector of PMTs, and each PMT can be +of any internal type. On the other hand, uniform PMTs are of a +specific data type which come in the form: + +- (u)int8 +- (u)int16 +- (u)int32 +- (u)int64 +- float32 +- float64 +- complex 32 (std::complex) +- complex 64 (std::complex) + +That is, the standard sizes of integers, floats, and complex types of +both signed and unsigned. + +Vectors have a well-defined interface that allows us to make, set, +get, and fill them. We can also get the length of a vector with +pmt::pmt_length. + +For standard vectors, these functions look like: + +- bool pmt::pmt_is_vector(pmt_t x) +- pmt_t pmt::pmt_make_vector(size_t k, pmt_t fill) +- pmt_t pmt::pmt_vector_ref(pmt_t vector, size_t k) +- void pmt::pmt_vector_set(pmt_t vector, size_t k, pmt_t obj) +- void pmt::pmt_vector_fill(pmt_t vector, pmt_t fill) + +Uniform vectors have the same types of functions, but they are data +type-dependent. The following list tries to explain them where you +substitute the specific data type prefix for \a dtype (prefixes being: +u8, u16, u32, u64, s8, s16, s32, s64, f32, f64, c32, c64). + +- bool pmt::pmt_is_(dtype)vector(pmt_t x) +- pmt_t pmt::pmt_make_(dtype)vector(size_t k, (dtype) fill) +- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const (dtype*) data) +- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const std::vector data) +- pmt_t pmt::pmt_(dtype)vector_ref(pmt_t vector, size_t k) +- void pmt::pmt_(dtype)vector_set(pmt_t vector, size_t k, (dtype) x) +- const dtype* pmt::pmt_(dtype)vector_elements(pmt_t vector, size_t &len) +- dtype* pmt::pmt_(dtype)vector_writable_elements(pmt_t vector, size_t &len) + +\b Note: We break the contract with vectors. The 'set' functions +actually change the data underneath. It is important to keep track of +the implications of setting a new value as well as accessing the +'vector_writable_elements' data. Since these are mostly standard data +types, sets and gets are atomic, so it is unlikely to cause a great +deal of harm. But it's only unlikely, not impossible. Best to use +mutexes whenever manipulating data in a vector. + + +\subsection blob BLOB + +A BLOB is a 'binary large object' type. In PMT's, this is actually +just a thin wrapper around a u8vector. + +\section pairs Pairs + +Pairs are inspired by LISP 'cons' data types, so you will find the +language here comes from LISP. A pair is just a pair of PMT +objects. They are manipulated using the following functions: + +- bool pmt::pmt_is_pair (const pmt_t &obj): Return true if obj is a pair, else false +- pmt_t pmt::pmt_cons(const pmt_t &x, const pmt_t &y): construct new pair +- pmt_t pmt::pmt_car(const pmt_t &pair): get the car of the pair (first object) +- pmt_t pmt::pmt_cdr(const pmt_t &pair): get the cdr of the pair (second object) +- void pmt::pmt_set_car(pmt_t pair, pmt_t value): Stores value in the car field +- void pmt::pmt_set_cdr(pmt_t pair, pmt_t value): Stores value in the cdr field + + +\section serdes Serializing and Deserializing + +It is often important to hide the fact that we are working with PMTs +to make them easier to transmit, store, write to file, etc. The PMT +library has methods to serialize data into a string buffer or a +string and then methods to deserialize the string buffer or string +back into a PMT. We use this extensively in the metadata files (see +\ref page_metadata). + +- bool pmt::pmt_serialize(pmt_t obj, std::streambuf &sink) +- std::string pmt::pmt_serialize_str(pmt_t obj) +- pmt_t pmt::pmt_deserialize(std::streambuf &source) +- pmt_t pmt::pmt_deserialize_str(std::string str) + +For example, we will serialize the data above to make it into a string +ready to be written to a file and then deserialize it back to its +original PMT. + +\code +from gruel import pmt + +key0 = pmt.pmt_intern("int") +val0 = pmt.pmt_from_long(123) + +key1 = pmt.pmt_intern("double") +val1 = pmt.pmt_from_double(5.4321) + +# Make an empty dictionary +a = pmt.pmt_make_dict() + +# Add a key:value pair to the dictionary +a = pmt.pmt_dict_add(a, key0, val0) +a = pmt.pmt_dict_add(a, key1, val1) + +pmt.pmt_print(a) + +ser_str = pmt.pmt_serialize_str(a) +print ser_str + +b = pmt.pmt_deserialize_str(ser_str) +pmt.pmt_print(b) + +\endcode + +The line where we 'print ser_str' will print and parts will be +readable, but the point of serializing is not to make a human-readable +string. This is only done here as a test. + + +\section printing Printing + +We have used the pmt::pmt_print function in these examples to nicely +print the contents of a PMT. Another way to print the contents is +using the overloaded "<<" operator with a stream buffer object. In +C++, we can inline print the contents of a PMT like: + +\code +pmt::pmt_t a pmt::pmt_from_double(1.0); +std::cout << "The PMT a contains " << a << std::endl; +\endcode + +*/ -- cgit From 6d8161a0b0c88f2faf090a80c74eb03422278289 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 18 Dec 2012 15:31:20 -0500 Subject: docs: Restructuring main page to point to new pages describing features in GR. --- docs/doxygen/other/main_page.dox | 6 ++++++ docs/doxygen/other/msg_passing.dox | 3 +++ 2 files changed, 9 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 282682464..abdc21b0c 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -37,6 +37,12 @@ More details on packages in GNU Radio: \li \ref page_qtgui \li \ref page_uhd \li \ref page_vocoder + +More details on GNU Radio concepts: +\li \ref page_pmt +\li \ref page_msg_passing +\li \ref page_metadata +\li \ref volk_guide \li \ref page_pfb diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox index 564a71c4a..aea0ac94a 100644 --- a/docs/doxygen/other/msg_passing.dox +++ b/docs/doxygen/other/msg_passing.dox @@ -26,6 +26,9 @@ communicate back and forth between external applications and GNU Radio. The new message passing interface handles these cases, although it does so on an asynchronous basis. +The message passing interface heavily relies on Polymorphic Types +(PMTs) in GNU Radio. For further information about these data +structures, see the page \ref page_pmt. \section api Message Passing API -- cgit From 5faae9df3ad16bceb24b65fed63a8a8766b48ee9 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 2 Jan 2013 12:13:44 -0500 Subject: docs: fixing typo. --- docs/doxygen/other/metadata.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox index f867a06f2..b527b2100 100644 --- a/docs/doxygen/other/metadata.dox +++ b/docs/doxygen/other/metadata.dox @@ -298,7 +298,7 @@ The file sink example can be switched to use a signal source instead of a UHD source, but no extra tagged data is used in this mode. The file source example pushes the data stream to a new raw file while -a tag debugger block prints out any tags observed in the metedata +a tag debugger block prints out any tags observed in the metadata file. A QT GUI time sink is used to look at the signal as well. The versions with 'vector' in the name are similar except they use -- cgit From 01eab0c7e283db9c1cfff0a26296a49128062cca Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 19 Dec 2012 13:38:24 -0500 Subject: core: working thread affinity concept into gr_blocks. Example in gnuradio-core/src/examples/mp-sched/affinity_set.py Documentation describing API in docs/doxygen/other/thread_affinity.dox --- docs/doxygen/other/thread_affinity.dox | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/doxygen/other/thread_affinity.dox (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/thread_affinity.dox b/docs/doxygen/other/thread_affinity.dox new file mode 100644 index 000000000..fbbc449a4 --- /dev/null +++ b/docs/doxygen/other/thread_affinity.dox @@ -0,0 +1,65 @@ +/*! \page page_affinity Block Thread Affinity + +\section intro Introduction + +In the thread-per-block scheduler, you can set the block's core +affinity. Each block can be pinned to a group cores or be set back +to use the standard kernel scheduler. + +The implementation is done by adding new functions to the GRUEL +library: + +\code + gr_thread_t get_current_thread_id(); + void thread_bind_to_processor(unsigned int n); + void thread_bind_to_processor(const std::vector &mask); + void thread_bind_to_processor(gr_thread_t thread, unsigned int n); + void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask); + void thread_unbind(); + void thread_unbind(gr_thread_t thread); +\endcode + +The ability to set a thread's affinity to a core or groups of cores is +not implemented in the Boost thread library, and so we have made our +own portability library. In particular, the gruel::gr_thread_t type is +defined as the thread type for the given system. The other functions +are designed to be portable as well by calling the specific +implementation for the thread affinity for a particular platform. + +There are functions to set a thread to a group of cores. If the thread +is not given, the current thread is used. If a single number is +passed, only that core is set (this is equivalent to a core mask with +just a single value). + +Similarly, there are functions to unset the affinity. This practically +implements the setting of the thread's affinity to all possible +cores. Again, the function that does not take a thread argument unsets +the affinity for the current thread. + + +\section api GNU Radio Block API + +Each block has two new data members: + +- threaded: a boolean value that is true if the block is attached to a + thread. +- thread: a gruel::gr_thread_t handle to the block's thread. + +A block can set and unset it's affinity at any time using the +following member functions: + +- gr_block::set_processor_affinity(const std::vector &mask) +- gr_block::unset_processor_affinity() + +Where \p mask is a vector of core numbers to set the thread's affinity +to. + +The current core affinity can be retrieved using the member function: + +- gr_block::processor_affinity() + +When set before the flowgraph is started, the scheduler will set the +thread's affinity when it is started. When already running, the +block's affinity will be immediately set. + +*/ -- cgit From 3643a858e3f4e52fc9c9a3310f779a9f77ed308e Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 16 Feb 2013 16:23:12 -0500 Subject: docs: adding section to main page explaining config files. --- docs/doxygen/other/main_page.dox | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'docs/doxygen/other') diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index abdc21b0c..e7d4685f7 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -329,4 +329,77 @@ they can also serve as examples. See the gr_complex_to_xxx.h file for examples of various blocks that make use of Volk. +\section prefs Configuration / Preference Files + +GNU Radio defines some of its basic behavior through a set of +configuration files located in +${prefix}/etc/gnuradio/conf.d. Different components have different +files listed in here for the various properties. These will be read +once when starting a GNU Radio application, so updates during runtime +will not affect them. + +The configuration files use the following format: + +\code +# Stuff from section 1 +[section1] +var1 = value1 +var2 = value2 # value of 2 + +# Stuff from section 2 +[section2] +var3 = value3 +\endcode + +In this file, the hash mark ('#') indicates a comment and blank lines +are ignored. Section labels are defined inside square brackets as a +group distinguisher. All options must be associated with a section +name. The options are listed one per line with the option name is +given followed by an equals ('=') sign and then the value. All section +and option names must not have white spaces (actually, all white +spaces are ignored). + +The value of an option can be a string or number and retrieved through +a few different interfaces. There is a single preference object +created when GNU Radio is launched. In Python, you can get this by +making a new variable: + +\code +p = gr.prefs() +\endcode + +Similarly, in C++, we get a reference to the object by explicitly +calling for the singleton of the object: + +\code + gr_prefs *p = gr_prefs::singleton(); +\endcode + +The methods associated with this preferences object are (from class gr_prefs): + +\code + bool has_section(string section) + bool has_option(string section, string option) + string get_string(string section, string option, string default_val) + bool get_bool(string section, string option, bool default_val) + long get_long(string section, string option, long default_val) + double get_double(string section, string option, double default_val) +\endcode + +When setting a Boolean value, we can use 0, 1, "True", "true", +"False", "false", "On", "on", "Off", and "off". + +All configuration preferences in these files can also be overloaded by +an environmental variable. The environmental variable is named based +on the section and option name from the configuration file as: + +\code + GR_CONF_
_