OSDN Git Service

Add toppers-jsp/ in nxtOSEK_v205b0.zip. They are licensed under TOPPERS license.
[nxt-jsp/etrobo-atk.git] / nxtOSEK / toppers_jsp / sample / cxx_sample2.cpp
diff --git a/nxtOSEK/toppers_jsp/sample/cxx_sample2.cpp b/nxtOSEK/toppers_jsp/sample/cxx_sample2.cpp
new file mode 100644 (file)
index 0000000..720c337
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ *  TOPPERS/JSP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Just Standard Profile Kernel
+ * 
+ *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ *                              Toyohashi Univ. of Technology, JAPAN
+ *  Copyright (C) 2003-2004 Takagi Nobuhisa
+ * 
+ *  ¾åµ­Ãøºî¸¢¼Ô¤Ï¡¤°Ê²¼¤Î (1)¡Á(4) ¤Î¾ò·ï¤«¡¤Free Software Foundation 
+ *  ¤Ë¤è¤Ã¤Æ¸øɽ¤µ¤ì¤Æ¤¤¤ë GNU General Public License ¤Î Version 2 ¤Ëµ­
+ *  ½Ò¤µ¤ì¤Æ¤¤¤ë¾ò·ï¤òËþ¤¿¤¹¾ì¹ç¤Ë¸Â¤ê¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¡ÊËÜ¥½¥Õ¥È¥¦¥§¥¢
+ *  ¤ò²þÊѤ·¤¿¤â¤Î¤ò´Þ¤à¡¥°Ê²¼Æ±¤¸¡Ë¤ò»ÈÍÑ¡¦Ê£À½¡¦²þÊÑ¡¦ºÆÇÛÉۡʰʲ¼¡¤
+ *  ÍøÍѤȸƤ֡ˤ¹¤ë¤³¤È¤ò̵½þ¤ÇµöÂú¤¹¤ë¡¥
+ *  (1) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¥½¡¼¥¹¥³¡¼¥É¤Î·Á¤ÇÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤¾åµ­¤ÎÃøºî
+ *      ¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­¤Î̵Êݾڵ¬Ä꤬¡¤¤½¤Î¤Þ¤Þ¤Î·Á¤Ç¥½¡¼
+ *      ¥¹¥³¡¼¥ÉÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¡¥
+ *  (2) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤¥é¥¤¥Ö¥é¥ê·Á¼°¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ *      ÍѤǤ­¤ë·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
+ *      ¼Ô¥Þ¥Ë¥å¥¢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ­¤ÎÃøºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­
+ *      ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ *  (3) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤µ¡´ï¤ËÁȤ߹þ¤à¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ *      ÍѤǤ­¤Ê¤¤·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤¼¡¤Î¤¤¤º¤ì¤«¤Î¾ò·ï¤òËþ¤¿¤¹¤³
+ *      ¤È¡¥
+ *    (a) ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥­¥å¥á¥ó¥È¡ÊÍøÍѼԥޥ˥奢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ­¤ÎÃø
+ *        ºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ­¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ *    (b) ºÆÇÛÉۤηÁÂÖ¤ò¡¤Ê̤ËÄê¤á¤ëÊýË¡¤Ë¤è¤Ã¤Æ¡¤TOPPERS¥×¥í¥¸¥§¥¯¥È¤Ë
+ *        Êó¹ð¤¹¤ë¤³¤È¡¥
+ *  (4) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»
+ *      ³²¤«¤é¤â¡¤¾åµ­Ãøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤òÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ * 
+ *  ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¤ÌµÊݾڤÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡¥¾åµ­Ãøºî¸¢¼Ô¤ª
+ *  ¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤Ï¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ë´Ø¤·¤Æ¡¤¤½¤ÎŬÍѲÄǽÀ­¤â
+ *  ´Þ¤á¤Æ¡¤¤¤¤«¤Ê¤ëÊݾڤâ¹Ô¤ï¤Ê¤¤¡¥¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľ
+ *  ÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤¿¤¤¤«¤Ê¤ë»³²¤Ë´Ø¤·¤Æ¤â¡¤¤½¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¡¥
+ * 
+ *  @(#) $Id: cxx_sample2.cpp,v 1.4 2004/09/17 09:11:34 honda Exp $
+ */
+
+/*
+ *  C++¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à(2)¤ÎËÜÂÎ
+ *
+ *  ¤³¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤Ï¡Öů³Ø¼Ô¤Î¿©»ö¡×¤ò¥Ù¡¼¥¹¤È¤·¤Æ¡¢C++¤Î³Æµ¡Ç½
+ *  ¤Î¥Ç¥â¤ò¹Ô¤Ã¤Æ¤¤¤ë¡£
+ *  5¿Í¤Îů³Ø¼Ô¤¬º¸±¦¤Î¥Õ¥©¡¼¥¯¤ò¼è¤ëºÝ¡¢¸Î°Õ¤Ë¥Ç¥Ã¥É¥í¥Ã¥¯¤òȯÀ¸¤µ¤»¡¢
+ *  ¥¿¥¤¥à¥¢¥¦¥È¤ò¸¡½Ð¤·¤¿»þÅÀ¤ÇC++¤ÎÎã³°¤òÁ÷½Ð¤·¤Æ¤¤¤ë¡£
+ *
+ *  Æ°ºîÃæ¤Ë'q'¤òÆþÎϤ¹¤ë¤ÈÆ°ºî¤òÄä»ß¤¹¤ë¤³¤È¤¬¤Ç¤­¡¢restart? [y|n]¤ËÂÐ
+ *  ¤·¤Æ'y'¤òÆþÎϤ¹¤ì¤ÐºÆµ¯Æ°¡¢'n'¤òÆþÎϤ¹¤ì¤Ð½ªÎ»¤¹¤ë¡£
+ *  ¤Þ¤¿¡¢Æ°ºîÃæ¤Ë'a'¤òÆþÎϤ¹¤ì¤Ð¥¢¥Ü¡¼¥È¤¹¤ë¡£
+ */
+
+#include <t_services.h>
+#include <cstdlib>
+#include <new>
+#include "kernel_id.h"
+#include "cxx_sample2.h"
+
+//     Èó¥Þ¥ë¥Á¥¿¥¹¥¯¥Æ¥¹¥È¥¯¥é¥¹
+//     ÀÅŪ¥ª¥Ö¥¸¥§¥¯¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤È¥Ç¥¹¥È¥é¥¯¥¿¤ÎÆ°ºî¥µ¥ó¥×¥ë
+class non_multitask_test
+{
+       int* x_;
+public:
+       non_multitask_test()
+               : x_(new int(12345))    // ¥«¡¼¥Í¥ëÈóÆ°ºî¾õÂ֤ǤÎnew±é»»»Ò
+       {
+       }
+       ~non_multitask_test()
+       {
+               if (*x_== 12345)
+                       syslog(LOG_NOTICE,"non-multitask test succeeded");
+               else
+                       syslog(LOG_NOTICE,"non-multitask test failed");
+               delete x_;                              // ¥«¡¼¥Í¥ëÈóÆ°ºî¾õÂ֤ǤÎdelete±é»»»Ò
+               x_ = 0;
+       }
+} test;
+
+class timeout_error
+{
+};
+
+// µ¼»÷Íð¿ô
+int rnd()
+{
+       static unsigned int seed = 1;
+       loc_cpu();
+       seed = seed * 1566083941UL + 1;
+       unl_cpu();
+       return (seed >> 16) % 0x7fff;
+}
+
+//     ¥Õ¥©¡¼¥¯¥¯¥é¥¹
+class fork
+{
+       ID semid_;
+       bool used_;
+public:
+       explicit fork(int semid)
+               : semid_(semid), used_(false)
+       {
+       }
+       ~fork()
+       {
+               if (used_)
+                       give();
+       }
+       ID id() const { return semid_; }
+       bool is_used() const { return used_; }
+       void take()
+       {
+               if (twai_sem(semid_, 500*5) == E_TMOUT)
+                       throw timeout_error();
+               used_ = true;
+       }
+       void give()
+       {
+               used_ = false;
+               sig_sem(semid_);
+       }
+};
+
+fork* p_fork[5];
+
+//     Å¯³Ø¼Ô¥¯¥é¥¹
+class philosopher
+{
+       ID              tskid_;
+       fork* left_;
+       fork* right_;
+public:
+       explicit philosopher(int tskid, fork* left, fork* right)
+               : tskid_(tskid),
+                       left_(left), right_(right)
+       {
+               syslog(LOG_NOTICE,"philosofer #%d", tskid);
+       }
+       void think()
+       {
+               syslog(LOG_NOTICE, "#%d thinking...", tskid_);
+               dly_tsk(100 * (rnd() % 5 + 1));
+       }
+       void eat()
+       {
+               syslog(LOG_NOTICE, "#%d eat up", tskid_);
+               dly_tsk(100 * (rnd() % 5 + 1));
+       }
+       void run()
+       {
+               for (;;)
+               {
+                       try
+                       {
+                               //      °Õ¿ÞŪ¤Ë¥Ç¥Ã¥É¥í¥Ã¥¯¤òȯÀ¸¤µ¤»¤ë¡£
+                               left_->take();
+                               syslog(LOG_NOTICE, "#%d take left fork(%d)", tskid_, left_->id());
+
+                               dly_tsk(100 * (rnd() % 5 + 1));
+
+                               right_->take();
+                               syslog(LOG_NOTICE, "#%d take right fork(%d)", tskid_, right_->id());
+
+                               eat();
+
+                               left_->give();
+                               syslog(LOG_NOTICE, "#%d give left fork(%d)", tskid_, left_->id());
+                               right_->give();
+                               syslog(LOG_NOTICE, "#%d give right fork(%d)", tskid_, right_->id());
+                               think();
+                       }
+                       catch (timeout_error&)
+                       {
+                               //      ¥¿¥¤¥à¥¢¥¦¥È¤Ë¤è¤ê¥Ç¥Ã¥É¥í¥Ã¥¯¤ò¸¡½Ð¤¹¤ë¤È¡¢¥Õ¥©¡¼¥¯¤òÊü¤¹¡£
+                               syslog(LOG_NOTICE, "#%d !!!! timeout error !!!!", tskid_);
+                               if (left_->is_used())
+                               {
+                                       left_->give();
+                                       syslog(LOG_NOTICE, "#%d give left fork(%d)", tskid_, left_->id());
+                               }
+                               if (right_->is_used())
+                               {
+                                       right_->give();
+                                       syslog(LOG_NOTICE, "#%d give right fork(%d)", tskid_, right_->id());
+                               }
+                               rot_rdq(TPRI_SELF);
+                       }
+               }
+       }
+};
+
+void task(VP_INT exinf)
+{
+       _toppers_cxxrt_reset_specific();        // ¥¿¥¹¥¯¤ÎºÆµ¯Æ°¤ò²Äǽ¤Ë¤¹¤ë¤¿¤á¤Î½é´ü²½½èÍý
+       ID              tskid = ID(exinf);
+       fork* left      = p_fork[(tskid - 1) % 5];
+       fork* right = p_fork[(tskid - 1 + 4) % 5];
+       philosopher phil(tskid, left, right);
+       phil.run();
+}
+
+//     std::atexit¤ÇÅÐÏ¿¤¹¤ë½ªÎ»»þ´Ø¿ô
+void finish()
+{
+       syslog(LOG_NOTICE, "finish");
+}
+
+
+//     ¥á¥¤¥ó¥¿¥¹¥¯
+void main_task(VP_INT exinf)
+{
+       serial_ctl_por(TASK_PORTID, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV));
+       syslog(LOG_NOTICE,"Sample program starts (exinf = %d)", exinf);
+
+       std::atexit(finish);
+
+       try
+       {
+               for (;;)
+               {
+                       for (ID semid = 1; semid <= 5; semid++)
+                               p_fork[semid - 1] = new fork(semid);
+
+                       for (ID tskid = 1; tskid <= 5; tskid++)
+                               act_tsk(tskid);
+
+                       char c;
+                       do
+                       {
+                               serial_rea_dat(TASK_PORTID, &c, 1);
+                               if (c == 'a')
+                                       std::abort();
+                       } while (c != 'q' && c != 'Q');
+
+                       for (ID tskid = 1; tskid <= 5; tskid++)
+                       {
+                               ter_tsk(tskid);
+                       }
+
+                       for (ID semid = 1; semid <= 5; semid++)
+                       {
+                               delete p_fork[semid - 1];
+                               p_fork[semid - 1] = 0;
+                       }
+
+                       do
+                       {
+                               syslog(LOG_NOTICE, "restart? [y|n] ");
+                               serial_rea_dat(TASK_PORTID, &c, 1);
+                       } while (c != 'y' && c != 'n');
+
+                       if (c == 'n')
+                               break;
+               }
+
+               syslog(LOG_NOTICE, "multitask test succeeded");
+       }
+       catch (std::bad_alloc&)
+       {
+               syslog(LOG_NOTICE, "multitask test failed");
+       }
+
+       std::exit(0);
+}
+