1) Updated Task and Priority Management tutorial:
   Uses defauilt main task instead of the blinky task for the examples.
   Updated the picture use main task.
   Removed Comparing Task Priority section.
2) Updated Log module documentation


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/commit/19e0f48f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/tree/19e0f48f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/diff/19e0f48f

Branch: refs/heads/develop
Commit: 19e0f48ff80de0c727bb0c281707b0d1ecbc3f21
Parents: 3a6e4ff
Author: cwanda <[email protected]>
Authored: Wed Mar 29 19:16:48 2017 -0700
Committer: cwanda <[email protected]>
Committed: Wed Mar 29 19:16:48 2017 -0700

----------------------------------------------------------------------
 docs/os/modules/logs/logs.md           | 151 +++++++--------
 docs/os/tutorials/pics/task_lesson.png | Bin 12931 -> 23822 bytes
 docs/os/tutorials/tasks_lesson.md      | 273 ++++++----------------------
 3 files changed, 135 insertions(+), 289 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/19e0f48f/docs/os/modules/logs/logs.md
----------------------------------------------------------------------
diff --git a/docs/os/modules/logs/logs.md b/docs/os/modules/logs/logs.md
index 7da1a77..63ce68c 100644
--- a/docs/os/modules/logs/logs.md
+++ b/docs/os/modules/logs/logs.md
@@ -1,17 +1,31 @@
-## Mynewt Logging
-
-Apache Mynewt has a logging package (`apache-mynewt-core/sys/log`) to support
-logging of information within a Mynewt application.
+##Logging
 
+Mynewt log package supports logging of information within a Mynewt 
application.  It allows packages to define their own log streams with separate 
names.  It also allows an application to control the output destination of 
logs. 
 <br>
-
 ###Description
 
-Logging API is provided in `apache-mynewt-core/sys/log/include/log/log.h`.
+In the Mynewt OS, the log package comes in two versions:
+
+* The `sys/log/full` package implements the complete log functionality and API.
+
+* The `sys/log/stub` package implements stubs for the API.
 
-It allows packages to define their own log streams with separate 
-names.  It also allows an application to control the output destinations
-of logs. 
+Both packages export the `log` API, and any package that uses the log API must 
list `log` as a requirement  in its `pkg.yml` file as follows: 
+
+```no-highlight
+pkg.req_apis:
+    - log
+```
+
+<br>
+The application's `pkg.yml` file specifies the version of the log package to 
use.
+A project that requires the full logging capability must list the 
`sys/log/full` package as a dependency in its `pkg.yml` file:
+```no-highlight
+pkg.deps:
+    - sys/log/full
+```
+<br>
+You can use the `sys/log/stub` package if you want to build your application 
without logging to reduce code size.
 
 <br>
 
@@ -24,19 +38,19 @@ these at compile time to ensure the code size limits are 
met.
 
 A compiler flag `LOG_LEVEL` can be set  in your `target.cflags` or within
 your app `pkg.cflags` files to set the compile time log level.   The 
-log level are defined in `apache-mynewt-core/sys/log/include/log/log.h`
+log level are defined in `/sys/log/full/include/log/log.h`
 but must be added by number to your `yml` file.
 
 For example:
 
 ```no-highlight
-    pkg.cflags -DLOG_LEVEL=8
+    pkg.cflags -DLOG_LEVEL=3
 ```
 
 or 
 
 ```no-highlight
-    newt target set my_target cflags=-DLOG_LEVEL=8
+    newt target set my_target cflags=-DLOG_LEVEL=3
 ```
 
 would both set the compile-time log level to `LOG_LEVEL_ERROR`.  All logs
@@ -50,20 +64,18 @@ system.
 
 ### Log
 
-Each log stream requires a log structure to define its  logging properties.
-It is typical for modules to extern this structure.
-
+Each log stream requires a `log` structure to define its  logging properties. 
 <br>
 
 ### Log Handler
 
-To use logs, a log-handler is required, which is responsible for handling
-the I/O from the log.  The log package comes with two pre-built log handlers.
+To use logs, a log handler that handles the I/O from the log is required.  The 
log package comes with three pre-built log handlers:
 
 * console -- streams log events directly to the console port.  Does
 not support walking and reading.
 * cbmem -- writes/reads log events to a circular buffer.  Supports walking 
-and reading for access by `newtmgr` and shell commands.
+and reading for access by newtmgr and shell commands.
+* fcb -- writes/reads log events to a [flash circular 
buffer](/os/modules/fcb/fcb.md). Supports walking and reading for access by 
newtmgr and shell commands.
 
 In addition, it is possible to create custom log handlers for other methods.
 Examples may include
@@ -72,101 +84,96 @@ Examples may include
 * Flat flash buffer
 * Streamed over some other interface
 
-To use logging, you will not typically need to create your own log handler.
-You can use one of the two supplied above. 
+To use logging, you typically do not need to create your own log handler.  You 
can use one of the pre-built ones.
 
-In Mynewt today, each module will register its logs with a default log handler.
-Its up to the application to use or override this log handler for its 
-specific purposes.  See below for an example.
+A package or an application must define a variable of type `struct log` and 
register a log handler for it with the log package. It must call the 
`log_register()` function to specify the log handler to use:
 
-<br>
+```c
+log_register(char *name, struct log *log, const struct log_handler *lh, void 
*arg, uint8_t level)
 
-### Typical use of logging when writing an application 
+```
 
-When writing an application that is using other's log modules, you 
-may want to override their log handlers and log levels.
+The parameters are:
 
-Add the logging to your package file.
+* `name`- Name of the log stream.
+* `log` - Log instance to register,
+* `lh` - Pointer to the log handler. You can specify one of the pre-built 
ones: 
+    * `&log_console_handler` for console
+    * `&log_cbm_handler`  for  circular buffer 
+    * `&log_fcb_handler` for flash circular buffer
+* `arg` - Opaque argument that the specified log handler uses. The value of 
this argument depends on the log handler you specify:
+    * NULL for the `log_console_handler`.
+    * Pointer to an initialized `cbmem` structure (see `util/cbmem` package) 
for the `log_cbm_handler`.
+    * Pointer to an initialized `fcb_log` structure (see `fs/fcb` package) for 
the `log_fcb_handler`. 
 
-```no-highlight
-    pkg.deps:
-        - "@apache-mynewt-core/sys/log"
-```
+Typically, a package that uses logging defines a global variable, such as 
`my_package_log`, of type `struct log`. The package can call the 
`log_register()` function with default values, but usually an application will 
override the logging properties and where to log to. There are two ways a 
package can allow an application to override the values:
 
-<br>
+* Define system configuration settings that an application can set and  the 
package can then call the `log_register()` function with the configuration 
values.
+* Make the `my_package_log` variable external and let the application call the 
`log_register()` function to specify a log handler for its specific purpose.    
 
-Initialize the logs in your startup code. It may look like this 
+
+###Configuring Logging for Packages that an Application Uses
+Here is an example of how an application can set the log handlers for the logs 
of the packages that the application includes.  
+
+In this example, the `package1` package defines the variable  `package1_log` 
of type `struct log` and externs the variable. Similarly, the `package2` 
package defines the variable `package2_log` and externs the variable.  The 
application sets logs for `package1` to use console and sets logs  for 
`package2` to use a circular buffer.
 
 ```c
-#include <module1/module1.h>
-#include <module3/module2.h>
-#include <module3/module3.h>
+#include <package1/package1.h>
+#include <package2/package2.h>
+#include <util/cbmem.h>
+
 #include <log/log.h>
 
-/* log to console */
-static struct log_handler app_log_handler;
+static uint32_t cbmem_buf[MAX_CBMEM_BUF];
+static struct cbmem cbmem;
+
 
-/* this has to be after all the modules are 
- * initialized and have registered
- * their log modules */
 void app_log_init(void)
 {
 
-    /* create a log handler for all logs . FOr this application
-    ** send them directly to the console port */
-    log_console_handler_init(&app_log_handler);
-    ...
-    /* set up logging for the modules appropriately */
-    module1_log.log_level = LOG_LEVEL_WARN;
-    module2_log.log_level = LOG_LEVEL_INFO;
-    module3_log.log_level = LOG_LEVEL_DEBUG;
-
-    /* set up a single handler for all modules */
-    module1_log.log_handler = &app_log_handler;
-    module2_log.log_handler = &app_log_handler;
-    module3_log.log_handler = &app_log_handler;
+
+   
+    log_register("package1_log", &package1_log, &log_console_handler, NULL, 
LOG_SYSLEVEL);
+
+    cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
+    log_register("package2_log", &package2_log, &log_cbmem_handler, &cbmem, 
LOG_SYSLEVEL);
+
 }
 ```
 
 <br>
 
-### Typical use of Logging when writing a module 
-
-When creating a package using its own logging, you can have this type of
-structure.  
+### Implementing a Package that Uses Logging
+This example shows how a package logs to console.  The package registers 
default logging properties to use the console, but allows an application to 
override the values. It defines the `my_package_log` variable and makes it 
external so an application can override log handler.
 
+Make the `my_package_log` variable external:
 ```c
 /* my_package.h*/
 
 /* pick a unique name here */
-extern struct log my_log;
+extern struct log my_package_log;
 ```
 
 <br>
 
-with an implementation in your module that looks like this: 
+Define the `my_package_log` variable and register the console log handler: 
 
 ```c
-
 /* my_package.c */
 
-struct log_handler log_console_handler;
-struct log my_log;
+struct log my_package_log;
 
 {
     ...
-    /* create a default handler for this log stream */
-    log_console_handler_init(&log_console_handler);
 
     /* register my log with a name to the system */
-    log_register("log", &my_log, &log_console_handler);
-
-    /* set up default log level for my package */
-    my_log.log_level = LOG_LEVEL_DEBUG;
+    log_register("log", &my_package_log, &log_console_handler, NULL, 
LOG_LEVEL_DEBUG);
 
-    LOG_DEBUG(&my_log, LOG_MODULE_DEFAULT, "bla");
-    LOG_DEBUG(&my_log, LOG_MODULE_DEFAULT, "bab");
+    LOG_DEBUG(&my_package_log, LOG_MODULE_DEFAULT, "bla");
+    LOG_DEBUG(&my_package_log, LOG_MODULE_DEFAULT, "bab");
 }
 ```
 
+###Log API and Log Levels
+For more information on the `log` API and log levels, see the 
`sys/log/full/include/log/log.h` header file.
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/19e0f48f/docs/os/tutorials/pics/task_lesson.png
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/pics/task_lesson.png 
b/docs/os/tutorials/pics/task_lesson.png
index 0ecb5e8..c10603f 100644
Binary files a/docs/os/tutorials/pics/task_lesson.png and 
b/docs/os/tutorials/pics/task_lesson.png differ

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/19e0f48f/docs/os/tutorials/tasks_lesson.md
----------------------------------------------------------------------
diff --git a/docs/os/tutorials/tasks_lesson.md 
b/docs/os/tutorials/tasks_lesson.md
index 39ff6ab..c107395 100644
--- a/docs/os/tutorials/tasks_lesson.md
+++ b/docs/os/tutorials/tasks_lesson.md
@@ -1,5 +1,5 @@
 
-#Core OS Lesson: Tasks and Priority Management
+#Tasks and Priority Management
 **Target Platform: Arduino M0 Pro** (or legacy Arduino Zero or Zero Pro, but 
not Arduino M0)
 
 This lesson is designed to teach core OS concepts and strategies encountered 
when 
@@ -21,12 +21,19 @@ You will need the following equipment:
 -   USB to Micro USB Cable
 
 ##Build Your Application
-To save time, we will simply modify the Blinky app. We'll add the Task 
Management code to
-the Blinky app. Follow the [*Arduino Zero Blinky 
tutorial*](http://mynewt.apache.org/os/tutorials/arduino_zero/) 
+To save time, we will simply modify the Blinky application. We'll add the Task 
Management code to
+the Blinky application. Follow the [*Arduino Zero Blinky 
tutorial*](http://mynewt.apache.org/os/tutorials/arduino_zero/) 
 to create a new project and build your bootloader and application. Finally, 
build and 
 load the application to your Arduino to verify that everything is in order. 
Now let’s get started!
 
+##Default Main Task
+During Mynewt system startup, Mynewt creates a default main task and executes 
the application `main()` function in the context of this task.  The main task 
priority defaults to 127 and can be configured with the `OS_MAIN_TASK_PRIO` 
system configuration setting.
+
+
+The blinky application only has the `main` task.  The `main()` function 
executes an infinite loop that toggles the led and sleeps for one second. 
+<br>
 ##Create a New Task
+
 The purpose of this section is to give an introduction to the important 
aspects of tasks 
 and how to properly initialize them. First, let’s define a second task 
called `work_task` 
 in main.c (located in apps/blinky/src):
@@ -44,7 +51,7 @@ Next, let’s take a look at what is required to initialize 
our new task.
 ### Task Stack
 The task stack is an array of type `os_stack_t` which holds the program stack 
frames. Mynewt gives 
 us the ability to set the stack size for a task giving the application 
developer room to optimize 
-memory usage. Since we’re not short on memory, our `blinky_stack` and 
`work_stack` are plenty large 
+memory usage. Since we’re not short on memory, our `work_stack` is plenty 
large 
 for the purpose of this lesson. Notice that the elements in our task stack are 
of type `os_stack_t` 
 which are generally 32 bits, making our entire stack 1024 Bytes.
 
@@ -56,10 +63,8 @@ which are generally 32 bits, making our entire stack 1024 
Bytes.
 Note: The `OS_STACK_ALIGN` macro is used to align the stack based on the 
hardware architecture.
 
 ### Task Function
-The task function is essentially an infinite loop which waits for some 
“event” to wake it up. In our 
-Blinky app the task function, named `blinky_task_handler()`, is initially 
called when we call `os_start()` 
-in `main()`. In general, the task function is where the majority of work is 
done by a task. Let’s write 
-a task function for `work_task` called `work_task_handler()`:
+
+A task function is essentially an infinite loop that waits for some 
“event” to wake it up.  In general, the task function is where the majority 
of work is done by a task.  Let’s write a task function for `work_task` 
called `work_task_handler()`:
 
 ```c
 void
@@ -95,8 +100,9 @@ Let’s set the priority of `work_task` to 0, because 
everyone knows that work i
 
 ### Initialization
 To initialize a new task we use 
[*os_task_init()*](http://mynewt.apache.org/os/core_os/task/os_task_init/) 
-which takes a number of arguments including our new task function, stack, and 
priority. Much like `blinky_task`, 
-we’re going to initialize `work_task` inside `init_tasks` to keep our main 
function clean. We'll set the task stack here and pass it to the 
`os_task_init()` function as well.
+which takes a number of arguments including our new task function, stack, and 
priority. 
+
+Add the `init_tasks()` function to initialize `work_task` to keep our main 
function clean. 
 
 ```c
 int
@@ -106,23 +112,44 @@ init_tasks(void)
     os_stack_t *work_stack;
     work_stack = malloc(sizeof(os_stack_t)*WORK_STACK_SIZE);
     
-    assert(pstack);
+    assert(work_stack);
     os_task_init(&work_task, "work", work_task_handler, NULL,
             WORK_TASK_PRIO, OS_WAIT_FOREVER, work_stack,
             WORK_STACK_SIZE);
 
-    tasks_initialized = 1;
     return 0;
 }
 ```
+<br>
+
+Add the call to `init_tasks()` in `main()` before the `while` loop:
+
+```c
+
+int
+main(int argc, char **argv)
+{
+
+        ...
+
+    /* Initialize the work task */
+    init_tasks();
+
+    while (1) {
+         ...
+    }
+}
+```
 
+<br>
 And that’s it! Now run your application using the newt run command.
 ```
 $ newt run arduino_blinky 0.0.0
 ```
+<br>
 When GDB appears press C then Enter to continue and … *wait, why doesn't our 
LED blink anymore?*
 
-
+<br>
 #### Review
 Before we run our new app, let’s review what we need in order to create a 
task. This is a general case for a new task called mytask:
 
@@ -146,7 +173,7 @@ mytask_handler(void *arg)
   }
 }
 ```
-**3)** Initialize task before calling `os_start()`:
+**3)** Initialize the task:
 ```c
 os_task_init(&mytask, "mytask", mytask_handler, NULL, 
             MYTASK_PRIO, OS_WAIT_FOREVER, mytask_stack,
@@ -160,11 +187,9 @@ place of) the lower priority task which is *running*. When 
a lower priority task
 priority task, the lower priority task’s context data (stack pointer, 
registers, etc.) is saved and the new 
 task is switched in.
 
-In our example, `work_task` has a higher priority than `blinky_task` and, 
because it is never put into a 
-*sleep* state, holds the processor focus on its context. Let’s give 
`work_task` a delay and some simulated 
-work to keep it busy. Because the delay is measured in os ticks, the actual 
number of ticks per second is 
-dependent on the board. Therefore, we multiply `OS_TICKS_PER_SEC`, which is 
defined in the MCU, by the 
-number of seconds we wish to delay.
+In our example, `work_task` (priority 0) has a higher priority than the `main` 
task (priority 127).  Since `work_task` is never put into a *sleep* state, it 
holds the processor focus on its context. 
+
+Let’s give `work_task` a delay and some simulated work to keep it busy. The 
delay is measured in os ticks and the actual number of ticks per second is 
dependent on the board. We multiply `OS_TICKS_PER_SEC`, which is defined in the 
MCU, by the number of seconds we wish to delay.
 
 ```c
 void
@@ -182,24 +207,25 @@ work_task_handler(void *arg)
         int i;
         for(i = 0; i < 1000000; ++i) {
             /* Simulate doing a noticeable amount of work */
-            hal_gpio_set(g_led_pin);
+            hal_gpio_write(g_led_pin, 1);
         }
-        os_time_delay(3*OS_TICKS_PER_SECOND);
+        os_time_delay(3 * OS_TICKS_PER_SEC);
     }
 }
 ```
+<br>
+In order to notice the LED changing, modify the time delay in `main()` to 
blink at a higher frequency.
 
-In order to notice the LED changing, modify the time delay in 
`blinky_task_handler()` to blink at a higher frequency.
 ```c
 os_time_delay(OS_TICKS_PER_SEC/10);
 ```
+<br>
 Before we run the app, let’s predict the behavior. With the newest additions 
to `work_task_handler()`, 
-our first action will be to sleep for three seconds. This will allow 
`blinky_task` to take over the CPU 
-and blink to its heart’s content. After three seconds, `work_task` will wake 
up and be made *ready to run*, 
-causing it to preempt `blinky_task`. The LED will then remain lit for a short 
period while `work_task` 
+our first action will be to sleep for three seconds. This allows the `main` 
task, running `main()`, to take over the CPU and blink to its heart’s 
content. After three seconds, `work_task` will wake up and be made *ready to 
run*. 
+This causes it to preempt the `main` task. The LED will then remain lit for a 
short period while `work_task` 
 loops, then blink again for another three seconds while `work_task` sleeps. 
 
-Voila, you should see that our prediction was correct! 
+You should see that our prediction was correct! 
 
 
 ###Priority Management Considerations
@@ -211,198 +237,11 @@ Some tasks, such as the Shell task, execute quickly and 
require almost instantan
 the Shell task should be given a high priority. On the other hand, tasks which 
may be communicating over 
 a network, or processing data, should be given a low priority in order to not 
hog the CPU.
 
-The diagram below showcases the different scheduling patterns we. would expect 
from swapping blinky and 
-work tasks priorities.
+The diagram below shows the different scheduling patterns we would expect when 
we set the `work_task` priority higher and lower than the `main` task priority. 
 
 
-![Task Scheduling](pics/task_lesson.png)
+![Task Scheduling](pics/task_lesson1.png)
 
-In the second case where `blinky_task` has a higher priority, the “work” 
done by `work_task` would be 
-executed during the millisecond delays in `blinky_task`, saving us idle time 
compared to the first case.
+In the second case where the `main` task has a higher priority, `work_task` 
runs and executes “work” when
+the `main` task sleeps, saving us idle time compared to the first case.
 
 **Note:** Defining the same priority for two tasks leads to somewhat undefined 
behavior and should be avoided.
-
-##Comparing Priority Strategies
-
-Instead of stepping through a bunch of changes to our blinky app, clone my 
task lesson application from 
-github and copy an existing target.
-
-Change directory into apps and clone the repository to get our new
-files:
-```
-$ cd apps
-$ git clone https://github.com/bgiori/mynewt_tasks_lesson.git
-```
-Change directory back to your project root and copy  the arduino_blinky target 
to a new target called task_tgt.
-```c
-$ newt target copy arduino_blinky task_tgt
-```
-Set a new app location.
-```c
-$ newt target set task_tgt app=apps/mynewt_tasks_lesson
-```
-
-Now let’s take a look at our new code. First, notice that we have abandoned 
blinking, instead 
-choosing to use the 
[*console*](http://mynewt.apache.org/latest/os/modules/console/console/) 
-and [*shell*](http://mynewt.apache.org/latest/os/modules/shell/shell/) to 
follow our tasks through execution.
-
-Additionally, we have a number of different tasks:
-
--   **Task A** (`a_task`):
-    -   **Priority**: 3 → 2
-    -   **Description**: Task A is supposed to represent a task which 
frequently does a small amount 
-    of work, such as one which rapidly polls a sensor for data. Much like 
`blinky_task`, Task A will 
-    loop 10,000 times then wait 1 millisecond. Priority is changed by 
`timer_task` after the first simulation.
-
--   **Task B** (`b_task`):
-    -   **Priority**: 2 → 3
-    -   **Description**: Task B is supposed to represent a task which does a 
large amount of work 
-    relatively infrequently, such as one which sends/receives data from the 
cloud. Like work\_task, 
-    Task B will loop 1,000,000 times then wait 3 seconds. Priority is changed 
by timer\_task after 
-    the first simulation.
-
--   **Timer Task** (`timer_task`):
-    -   **Priority**: 1
-    -   **Description**: With default settings, Timer Task will wait 20 
seconds then print the first 
-    simulations data for Task A and B. Timer task will then swap A and B’s 
priorities and restart the 
-    simulation. After the second simulation, timer will again print simulation 
data then compare the 
-    two and calculate a final speedup (simulation2 / simulation1).
-
-- **Shell Task**:
-    -   **Priority**: 0
-    -   **Description**: Task used by Shell behind the scenes to communicate 
with the serial port.
-
-### Connecting to the Serial Console
-
-Before running our new app, we must first connect to the serial console. First 
make sure the 
-mynewt_arduino_zero repository is set to the develop branch. (Remove once 
changes have been 
-moved to master). 
-```
-$ cd repos/mynewt_arduino_zero
-$ git checkout develop
-```
-
-You should already be familiar with the [Serial Port Setup and 
Configuration](../get_started/serial_access.md), but if
-you're not, you can go there now and then come back. 
-
-### Output Analysis
-
-Run our new target, task_tgt, and you should see an output similar to this:
-
-```
-Starting First Simulation...
-1:     Task B: 0% 
-78:     Task B: 1% 
-155:     Task B: 2% 
-257:     Task B: 3% 
-359:     Task B: 4% 
-461:     Task B: 5% 
-
-<snip>
-
-========== Timer Expired ==========
-
- >>> Task A <<<
-  Priority: 3
-  Loop count: 162849
-  Cycle count: 16.28
-  Run time: 1.40 sec
-
- >>> Task B <<<
-  Priority: 2
-  Loop count: 1345852
-  Cycle count: 1.34
-  Run time: 17.0 sec
-
- Total loops: 1508709
-
-20023:   Switching priorities and restarting...
-20111:   Task A looped
-20113:     Task B: 0% 
-20191:     Task B: 1% 
-20297:   Task A looped
-20356:     Task B: 2% 
-20483:   Task A looped
-20545:     Task B: 3% 
-20669:   Task A looped
-20734:     Task B: 4% 
-20855:   Task A looped
-20923:     Task B: 5% 
-
-<snip>
-
-========== Timer Expired ==========
-
- >>> Task A <<<
-  Priority: 2
-  Loop count: 1080000
-  Cycle count: 108.0
-  Run time: 9.28 sec
-
- >>> Task B <<<
-  Priority: 3
-  Loop count: 830356
-  Cycle count: 0.83
-  Run time: 10.72 sec
-
- Total loops: 1910404
-
-40058:
-
- Final Speedup (Sim2 / Sim1): 1.26
-
-```
-
-The console output reaffirms our previous prediction and makes both the 
scheduling differences 
-and subsequent efficiency boost far more apparent. Let’s take a look at 
scheduling differences 
-before we delve into efficiency.
-
-In the first case, where Task B’s priority is higher than that of Task A, we 
see A get starved 
-by Task B’s long execution time. **Starvation** occurs when one task hogs 
the processor, essentially 
-“starving” other tasks which also need to run. At the end of the first 20 
second simulation period, 
-Task A has only run for 1.4 seconds compared to task B’s 17 second running 
time – ouch. As explained 
-before, processes which are expected to run for long periods of time (e.g. 
network communication, 
-data processing) should be given higher priorities in order to combat 
starvation.
-
-In the second simulation with priorities swapped, we can see Task B only 
running during the 
-millisecond delays when Task A is *sleeping*. Although having Task B only run 
during these 
-delays slows its execution time, we benefit from un-starving Task A and using 
the processor 
-at a higher efficiency.
-
-The bottom line speedup gives us an immediate and clear indication that we 
have improved our 
-ability to process work (i.e throughput). In our second run, we processed an 
additional 400,000 
-loop iterations, equating to a 26% increase in efficiency. On a standard 
multi-core processor 
-found in every modern PC, a 1.26 speedup would be an ok result to adding 
multithreading capabilities 
-to a serial program. However, we accomplished this by simply setting 
priorities on a single core 
-processor – not bad!
-
-NOTE: Usually the the term “speedup” is used within a parallel programming 
context and refers 
-to the change in execution time between a serial and parallel program 
executing over the same 
-problem. In this case we’re using the term loosely to illustrate the 
priority change’s effect 
-on scheduling and throughput in our specific context.
-
-### Efficiency Isn’t Everything
-
-Using the processor during every OS tick isn’t always the best course of 
action. If we modify 
-Task A’s delay to a tenth of a millisecond and turn off the console output, 
we can boost our 
-speedup to 1.44. This, however, reduces our ability to process work from Task 
B who ends up 
-only completing 18% of its work cycle after the second simulation. That would 
mean, at that 
-rate, Task B would take over a minute to finish one cycle.
-
-Feel free to play around with the testing parameters to study the different 
changes yourself!
-
-###Conclusion
-
-Moving forward, tasks are just the tip of the iceberg. The 
[*scheduler*](http://mynewt.apache.org/latest/os/core_os/context_switch/context_switch/),
 
-[*event 
queues*](http://mynewt.apache.org/latest/os/core_os/event_queue/event_queue/), 
-[*semaphores*](http://mynewt.apache.org/latest/os/core_os/semaphore/semaphore/),
 and 
-[*mutexes*](http://mynewt.apache.org/latest/os/core_os/mutex/mutex/) also add 
to tasks functionality, 
-increasing our ability as the developer to control greater numbers of tasks 
more intricately. For 
-example, when we switch the tasks priority, we have to tell the scheduler that 
our tasks priorities 
-have changed, allowing us us to use priorities dynamically. When running 
multiple tasks, logging 
-through either the built-in 
[*Logs*](http://mynewt.apache.org/latest/os/modules/logs/logs/) module 
-(not covered in this lesson) or through the serial console/shell can be very 
useful for debugging 
-your application. In the end, the way you manage your tasks depends on the 
context of your 
-application. You should assign priorities based on execution time, urgency, 
and frequency, among 
-other things.
-
-Keep blinking and happy hacking!

Reply via email to