home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj8911.zip / KAR.LST < prev    next >
File List  |  1989-10-04  |  6KB  |  226 lines

  1. _DATE-FLOW MULTITASKING_
  2. by Rabindra Kar
  3.  
  4.  
  5. [LISTING ONE] 
  6.  
  7. /*  quad_eq.c -
  8.  *  Calculate roots of quadratic equation:  ax  + bx + c = 0
  9.  */
  10.  
  11. #include "stdio.h"
  12. #include "rmx.h"
  13. #include "math.h"
  14.  
  15. #define NUM_VALS 100
  16.  
  17. unsigned status;
  18. struct coeffs {double a, b, c;} y[NUM_VALS+1];
  19. double det;
  20. double num;
  21. double res;
  22.  
  23. /* Calculate determinant */
  24. determinant(i)
  25. unsigned i;
  26. {
  27.     det = y[i].b * y[i].b - 4 * y[i].a * y[i].c;
  28. }
  29.  
  30. /* Calculate numerator */
  31. numerator(i)
  32. unsigned i;
  33. {
  34.     num = pow(det,0.5) - y[i].b;
  35. }
  36.  
  37. /* Calculate, print result */
  38. result(i)
  39. unsigned i;
  40. {
  41.     res = num / (2 * y[i].a);
  42.     printf("Coeffs = %.1f,%.1f,%.1f  Root = %7.2f\n",
  43.                             y[i].a,y[i].b,y[i].c,res);
  44. }
  45.  
  46. main()
  47.   unsigned i;
  48.   /* Create input data. Done for convenience. Could have read the data
  49.    * from any input device.
  50.    */
  51.   for (i = 1; i < NUM_VALS; i++)
  52.     {y[i].a = (double)i; y[i].c = (double)i; y[i].b = 3*(double)i;}
  53.  
  54.   /* Compute the roots */
  55.   
  56.   for (i = 1; i < NUM_VALS; i++)
  57.   { 
  58.     determinant(i);
  59.     numerator(i);
  60.     result(i);
  61.   }
  62.   printf("\n");
  63. }
  64.  
  65.  
  66. [LISTING TWO] 
  67.  
  68. /****************************************************************************\
  69.  *  dflow.c -
  70.  *    Compute the roots of a quadratic equation using multitasking
  71.  *    and data flow concepts.
  72.  *  Operating System: iRMX II. Compiler: iC-286 V3.2
  73. \****************************************************************************/
  74.  
  75. #include "stdio.h"
  76. #include "rmx.h"
  77. #include "math.h"
  78.  
  79. #define NUM_VALS 100
  80.  
  81. unsigned status, task_t;
  82. FILE *fp;
  83.  
  84. /* "union" used to decompose a pointer into segment:offset */
  85. typedef struct {unsigned offset; unsigned sel;} ptr_s;
  86. union { unsigned *pointer; ptr_s ptr; } ptr_u;
  87.  
  88. /* Input data area */
  89. struct coeffs {double a, b, c;} y[NUM_VALS+1];
  90.  
  91. /* "DET" mailbox -
  92.  *      Output from main task; input to num_task
  93.  */
  94. double det = 0.0;
  95. unsigned index1 = 0;
  96.  
  97. /* "NUM" mailbox -
  98.  *      Output from num_task; input to res_task
  99.  */
  100. double num = 0.0;
  101. unsigned index2 = 0;
  102.  
  103. /************************ Computational tasks *************************/
  104.  
  105. det_task()
  106. {    /* Calculate determinant */
  107.   unsigned i;
  108.   for (i = 1; y[i].a != 0.0; i++)
  109.   {
  110.     while (det != 0.0) rq$sleep(0,&status);
  111.     index1++;
  112.     det = y[i].b * y[i].b - 4 * y[i].a * y[i].c;
  113.   }
  114. }
  115.  
  116. num_task()
  117. {    /* Calculate numerator */
  118.   while (y[index1].a != 0.0)
  119.   {
  120.     while ((det == 0.0) || (num != 0.0)) rq$sleep(0,&status);
  121.     index2++;
  122.     num = pow(det, 0.5) - y[index1].b;
  123.     det = 0.0;
  124.   }
  125.   rq$delete$task(0,&status);    /* Delete self */
  126. }
  127.  
  128. res_task()
  129. {    /* Calculate result, print on console */
  130.   double res;
  131.   while (y[index2].a != 0.0)
  132.   {
  133.     while (num == 0.0) rq$sleep(0,&status);
  134.     res = num / (2 * y[index2].a);
  135.     num = 0.0;
  136.     printf("Coeffs = %.1f,%.1f,%.1f  Root = %7.2f\n",
  137.                             y[index2].a, y[index2].b, y[index2].c, res);
  138.   }
  139.   printf("\n");
  140.   rq$delete$task(0,&status);    /* Delete self */
  141. }
  142.  
  143. /****************************** Main Program ******************************/
  144.  
  145. main()
  146.   unsigned i;
  147.   unsigned short pri;
  148.  
  149.   /* Create input data. Done for convenience. Could have read the data
  150.    * from any input device.
  151.    */
  152.   for (i = 1; i < NUM_VALS; i++)
  153.     {y[i].a = (double)i; y[i].c = (double)i; y[i].b = 3*(double)i;}
  154.  
  155.   y[NUM_VALS].a = 0.0;   /* 0.0 indicates end of input data */
  156.   
  157.   /* Place a pointer to any variable in union "ptr_u", so the data segment
  158.      of this program becomes known.
  159.    */
  160.   ptr_u.pointer = &status;
  161.   
  162.   /* Find the priority level that iRMX accords the main task */
  163.   pri = rq$get$priority (NULL, &status);
  164.  
  165.   /*
  166.    * Spawn the operation tasks. All have the same priority as main.
  167.    */
  168.   task_t = rq$create$task (pri, (long)det_task, ptr_u.ptr.sel,
  169.                      0L, 1024, 1, &status);
  170.   if (status != 0) printf("det_task create error = %u\n",status);
  171.  
  172.   task_t = rq$create$task (pri, (long)num_task, ptr_u.ptr.sel,
  173.                      0L, 1024, 1, &status);
  174.   if (status != 0) printf("num_task create error = %u\n",status);
  175.  
  176.   task_t = rq$create$task (pri, (long)res_task, ptr_u.ptr.sel,
  177.                      0L, 1024, 1, &status);
  178.   if (status != 0) printf("res_task create error = %u\n",status);
  179.  
  180.   /*
  181.    * Lower main task's priority so main() will be idled by OS while other
  182.    * tasks do computations. Will return here when input data is exhausted.
  183.    */
  184.   rq$set$priority (NULL, (pri+1), &status); 
  185.  
  186.   /*********************************************************************/
  187.  
  188.   rq$sleep(10, &status);     /* Let other tasks complete */
  189.   printf("\n  Done! \n");
  190.  
  191. }
  192.  
  193. [LISTING THREE]
  194.  
  195.  
  196. /* 
  197.  * This code is similar to "res_task()" in dflow.c, except
  198.  * that the computed result is output to a file instead of the (default)
  199.  * console screen.
  200.  *     This code could be added to dflow.c along with two statements in
  201.  * main() to: 1. create a "res_task2()" task, and 2. open a file for
  202.  * output with fp as its file pointer. By so doing, the I/O delay involved
  203.  * in waiting for console output could be overlapped with file output delays,
  204.  * thus speeding up the program. Of course, the results would then be
  205.  * distributed between the console and the output file.
  206.  */
  207.  
  208. res_task2()
  209. {    /* Calculate result, print to file */
  210.   double res;
  211.   
  212.   while (y[index2].a != 0.0)
  213.   {
  214.     while (num == 0.0) rq$sleep(0,&status);
  215.     res = num / (2 * y[index2].a);
  216.     num = 0.0;
  217.     fprintf(fp, "Coeffs = %.1f,%.1f,%.1f  root = %7.2f\n",
  218.                             y[index2].a, y[index2].b, y[index2].c, res);
  219.   }
  220.   rq$delete$task(0,&status);    /* Delete self */
  221. }
  222.  
  223.  
  224.