--- /dev/null
+/*
+ * 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);
+}
+