cmsis rtos demo: mutex
Revision 1:1308d7d6d53e, committed 2013-01-06
- Comitter:
- cnhzcy14
- Date:
- Sun Jan 06 15:03:44 2013 +0000
- Parent:
- 0:fba50ae123e6
- Commit message:
- comments
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Sun Jan 06 14:20:05 2013 +0000
+++ b/main.cpp Sun Jan 06 15:03:44 2013 +0000
@@ -1,8 +1,29 @@
+/*****************************************************************************
+ * DESCRIPTION:
+ * This example program illustrates the use of mutex variables
+ * in a threads program. This version was obtained by modifying the
+ * serial version of the program (dotprod_serial.c) which performs a
+ * dot product. The main data is made available to all threads through
+ * a globally accessible structure. Each thread works on a different
+ * part of the data. The main thread waits for all the threads to complete
+ * their computations, and then it prints the resulting sum.
+ * SOURCE: Vijay Sonnad, IBM
+ * MODIFICATOR: (Simon) CHENG Ye
+ * LAST REVISED: 06/JAN/2013
+ ******************************************************************************/
+
#include "mbed.h"
#include "cmsis_os.h"
Serial debug(USBTX, USBRX);
+
+/*
+ * The following structure contains the necessary information
+ * to allow the function "dotprod" to access its input data and
+ * place its output into the structure. This structure is
+ * unchanged from the sequential version.
+ */
typedef struct
{
double *a;
@@ -11,16 +32,26 @@
int veclen;
} DOTDATA;
+/* Define globally accessible variables and a mutex */
#define NUMTHRDS 4
-#define VECLEN 200
+#define VECLEN 200 //Use a smaller size vector for limited memeory space on mbed
DOTDATA dotstr;
osMutexId stdio_mutex;
osMutexDef(stdio_mutex);
-
-
+/*
+ * The function dotprod is activated when the thread is created.
+ * As before, all input to this routine is obtained from a structure
+ * of type DOTDATA and all output from this function is written into
+ * this structure. The benefit of this approach is apparent for the
+ * multi-threaded program: when a thread is created we pass a single
+ * argument to the activated function - typically this argument
+ * is a thread number. All the other information required by the
+ * function is accessed from the globally accessible structure.
+ */
void dotprod(void const *arg)
{
+ /* Define and use local variables for convenience */
osThreadId id;
int i, start, end, len ;
long offset;
@@ -33,12 +64,18 @@
x = dotstr.a;
y = dotstr.b;
+ /*
+ * Perform the dot product and assign result
+ * to the appropriate variable in the structure.
+ */
mysum = 0;
for (i=start; i<end ; i++)
- {
mysum += (x[i] * y[i]);
- }
+ /*
+ * Lock a mutex prior to updating the value in the shared
+ * structure, and unlock it upon updating.
+ */
osMutexWait(stdio_mutex, osWaitForever);
dotstr.sum += mysum;
printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum);
@@ -48,7 +85,6 @@
osThreadTerminate(id);
}
-
void t0(void const *argument) {dotprod(argument);}
osThreadDef(t0, osPriorityNormal, DEFAULT_STACK_SIZE);
@@ -61,22 +97,32 @@
void t3(void const *argument) {dotprod(argument);}
osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE);
-int main() {
+/*
+ * The main program creates threads which do all the work and then
+ * print out result upon completion. Before creating the threads,
+ * The input data is created. Since all threads update a shared structure, we
+ * need a mutex for mutual exclusion. The main thread needs to wait for
+ * all threads to complete, it waits for each one of the threads. We specify
+ * a thread attribute value that allow the main thread to join with the
+ * threads it creates. Note also that we free up handles when they are
+ * no longer needed.
+ */
+int main()
+{
debug.baud(57600);
long i;
double *a, *b;
- //void *status;
/* Assign storage and initialize values */
-
a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
- for (i=0; i<VECLEN*NUMTHRDS; i++) {
- a[i]=1;
- b[i]=a[i];
- }
+ for (i=0; i<VECLEN*NUMTHRDS; i++)
+ {
+ a[i]=1;
+ b[i]=a[i];
+ }
dotstr.veclen = VECLEN;
dotstr.a = a;
@@ -85,8 +131,13 @@
stdio_mutex = osMutexCreate(osMutex(stdio_mutex));
+ /* Create threads to perform the dotproduct */
for(i=0;i<NUMTHRDS;i++)
{
+ /* Each thread works on a different set of data.
+ * The offset is specified by 'i'. The size of
+ * the data for each thread is indicated by VECLEN.
+ */
if(i==0) osThreadCreate(osThread(t0), (void *)i);
if(i==1) osThreadCreate(osThread(t1), (void *)i);
if(i==2) osThreadCreate(osThread(t2), (void *)i);
Ye Cheng