diff --git a/src/core/common/tasklet.cpp b/src/core/common/tasklet.cpp index b46ef2841..b23bc8adc 100644 --- a/src/core/common/tasklet.cpp +++ b/src/core/common/tasklet.cpp @@ -38,37 +38,41 @@ namespace Thread { -Tasklet *TaskletScheduler::sHead = NULL; -Tasklet *TaskletScheduler::sTail = NULL; - -Tasklet::Tasklet(Handler aHandler, void *aContext) +Tasklet::Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext): + mScheduler(aScheduler), + mHandler(aHandler), + mContext(aContext), + mNext(NULL) { - mHandler = aHandler; - mContext = aContext; - mNext = NULL; } ThreadError Tasklet::Post(void) { - return TaskletScheduler::Post(*this); + return mScheduler.Post(*this); +} + +TaskletScheduler::TaskletScheduler(void): + mHead(NULL), + mTail(NULL) +{ } ThreadError TaskletScheduler::Post(Tasklet &aTasklet) { ThreadError error = kThreadError_None; - VerifyOrExit(sTail != &aTasklet && aTasklet.mNext == NULL, error = kThreadError_Busy); + VerifyOrExit(mTail != &aTasklet && aTasklet.mNext == NULL, error = kThreadError_Busy); - if (sTail == NULL) + if (mTail == NULL) { - sHead = &aTasklet; - sTail = &aTasklet; + mHead = &aTasklet; + mTail = &aTasklet; otSignalTaskletPending(); } else { - sTail->mNext = &aTasklet; - sTail = &aTasklet; + mTail->mNext = &aTasklet; + mTail = &aTasklet; } exit: @@ -77,15 +81,15 @@ exit: Tasklet *TaskletScheduler::PopTasklet(void) { - Tasklet *task = sHead; + Tasklet *task = mHead; if (task != NULL) { - sHead = sHead->mNext; + mHead = mHead->mNext; - if (sHead == NULL) + if (mHead == NULL) { - sTail = NULL; + mTail = NULL; } task->mNext = NULL; @@ -96,7 +100,7 @@ Tasklet *TaskletScheduler::PopTasklet(void) bool TaskletScheduler::AreTaskletsPending(void) { - return sHead != NULL; + return mHead != NULL; } void TaskletScheduler::RunNextTasklet(void) diff --git a/src/core/common/tasklet.hpp b/src/core/common/tasklet.hpp index a312f7984..3dac49ff1 100644 --- a/src/core/common/tasklet.hpp +++ b/src/core/common/tasklet.hpp @@ -38,6 +38,8 @@ namespace Thread { +class TaskletScheduler; + /** * @addtogroup core-tasklet * @@ -68,11 +70,12 @@ public: /** * This constructor creates a tasklet instance. * - * @param[in] aHandler A pointer to a function that is called when the tasklet is run. - * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aScheduler A reference to the tasklet scheduler. + * @param[in] aHandler A pointer to a function that is called when the tasklet is run. + * @param[in] aContext A pointer to arbitrary context information. * */ - Tasklet(Handler aHandler, void *aContext); + Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext); /** * This method puts the tasklet on the run queue. @@ -81,15 +84,12 @@ public: ThreadError Post(void); private: - /** - * This method is called when the tasklet is run. - * - */ void RunTask(void) { mHandler(mContext); } - Handler mHandler; ///< A pointer to a function that is called when the tasklet is run. - void *mContext; ///< A pointer to arbitrary context information. - Tasklet *mNext; ///< A pointer to the next tasklet in the run queue. + TaskletScheduler &mScheduler; + Handler mHandler; + void *mContext; + Tasklet *mNext; }; /** @@ -100,34 +100,40 @@ class TaskletScheduler { public: /** - * This static method enqueues a tasklet into the run queue. + * This constructor initializes the object. + * + */ + TaskletScheduler(void); + + /** + * This method enqueues a tasklet into the run queue. * * @param[in] aTasklet A reference to the tasklet to enqueue. * * @retval kThreadError_None Successfully enqueued the tasklet. * @retval kThreadError_Busy The tasklet was already enqueued. */ - static ThreadError Post(Tasklet &aTasklet); + ThreadError Post(Tasklet &aTasklet); /** - * This static method indicates whether or not there are tasklets pending. + * This method indicates whether or not there are tasklets pending. * * @retval TRUE If there are tasklets pending. * @retval FALSE If there are no tasklets pending. * */ - static bool AreTaskletsPending(void); + bool AreTaskletsPending(void); /** - * This static method runs the next tasklet. + * This method runs the next tasklet. * */ - static void RunNextTasklet(void); + void RunNextTasklet(void); private: - static Tasklet *PopTasklet(void); - static Tasklet *sHead; - static Tasklet *sTail; + Tasklet *PopTasklet(void); + Tasklet *mHead; + Tasklet *mTail; }; /** diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 4b500942a..ae0c89f64 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -67,7 +67,7 @@ void Mac::StartCsmaBackoff(void) } Mac::Mac(ThreadNetif &aThreadNetif): - mBeginTransmit(&HandleBeginTransmit, this), + mBeginTransmit(aThreadNetif.GetIp6().mTaskletScheduler, &HandleBeginTransmit, this), mAckTimer(&HandleAckTimer, this), mBackoffTimer(&HandleBeginTransmit, this), mReceiveTimer(&HandleReceiveTimer, this), diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 2f42f858e..a6ef0ac6a 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -327,6 +327,8 @@ public: Icmp mIcmp; Udp mUdp; + TaskletScheduler mTaskletScheduler; + private: void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto); ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive); diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index 830db0361..d4e3654d3 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace Thread { @@ -41,7 +42,7 @@ namespace Ip6 { Netif::Netif(Ip6 &aIp6): mIp6(aIp6), - mStateChangedTask(&HandleStateChangedTask, this) + mStateChangedTask(aIp6.mTaskletScheduler, &HandleStateChangedTask, this) { mCallbacks = NULL; mUnicastAddresses = NULL; diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index 1f46a35c2..a54dc50f1 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -80,12 +80,12 @@ static void *sDiscoverCallbackContext = NULL; void otProcessNextTasklet(void) { - TaskletScheduler::RunNextTasklet(); + sIp6->mTaskletScheduler.RunNextTasklet(); } bool otAreTaskletsPending(void) { - return TaskletScheduler::AreTaskletsPending(); + return sIp6->mTaskletScheduler.AreTaskletsPending(); } uint8_t otGetChannel(void) diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index a4662650f..638ed4ef6 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -56,7 +56,7 @@ MeshForwarder::MeshForwarder(ThreadNetif &aThreadNetif): mDiscoverTimer(&HandleDiscoverTimer, this), mPollTimer(&HandlePollTimer, this), mReassemblyTimer(&HandleReassemblyTimer, this), - mScheduleTransmissionTask(ScheduleTransmissionTask, this), + mScheduleTransmissionTask(aThreadNetif.GetIp6().mTaskletScheduler, ScheduleTransmissionTask, this), mNetif(aThreadNetif), mAddressResolver(aThreadNetif.GetAddressResolver()), mLowpan(aThreadNetif.GetLowpan()), diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 8511a0faa..993afc2cd 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -63,7 +63,7 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mNetworkData(aThreadNetif.GetNetworkDataLeader()), mParentRequestTimer(&HandleParentRequestTimer, this), mSocket(aThreadNetif.GetIp6().mUdp), - mSendChildUpdateRequest(&HandleSendChildUpdateRequest, this) + mSendChildUpdateRequest(aThreadNetif.GetIp6().mTaskletScheduler, &HandleSendChildUpdateRequest, this) { mDeviceState = kDeviceStateDisabled; mDeviceMode = ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeSecureDataRequest | ModeTlv::kModeFFD | diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 27d509f06..382c10b58 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -406,7 +406,7 @@ static uint8_t BorderRouterConfigToFlagByte(const otBorderRouterConfig &config) // ---------------------------------------------------------------------------- NcpBase::NcpBase(): - mUpdateChangedPropsTask(&UpdateChangedProps, this) + mUpdateChangedPropsTask(sIp6->mTaskletScheduler, &UpdateChangedProps, this) { mSupportedChannelMask = kPhySupportedChannelMask; mChannelMask = mSupportedChannelMask; diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp index 29187c2de..f791bfa6c 100644 --- a/src/ncp/ncp_spi.cpp +++ b/src/ncp/ncp_spi.cpp @@ -47,6 +47,8 @@ namespace Thread { static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t); static NcpSpi *sNcpSpi; +extern Ip6::Ip6 *sIp6; + extern "C" void otNcpInit(void) { sNcpSpi = new(&sNcpRaw) NcpSpi; @@ -86,8 +88,8 @@ static uint16_t spi_header_get_data_len(const uint8_t *header) NcpSpi::NcpSpi(): NcpBase(), - mHandleRxFrameTask(&HandleRxFrame, this), - mPrepareTxFrameTask(&PrepareTxFrame, this), + mHandleRxFrameTask(sIp6->mTaskletScheduler, &HandleRxFrame, this), + mPrepareTxFrameTask(sIp6->mTaskletScheduler, &PrepareTxFrame, this), mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer)) { memset(mEmptySendFrame, 0, kSpiHeaderLength); diff --git a/src/ncp/ncp_uart.cpp b/src/ncp/ncp_uart.cpp index b87f35279..e845333ae 100644 --- a/src/ncp/ncp_uart.cpp +++ b/src/ncp/ncp_uart.cpp @@ -44,6 +44,8 @@ namespace Thread { static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpUart), uint64_t); static NcpUart *sNcpUart; +extern Ip6::Ip6 *sIp6; + extern "C" void otNcpInit(void) { sNcpUart = new(&sNcpRaw) NcpUart; @@ -81,7 +83,7 @@ NcpUart::NcpUart(): mFrameDecoder(mRxBuffer, sizeof(mRxBuffer), &HandleFrame, &HandleError, this), mUartBuffer(), mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer)), - mUartSendTask(EncodeAndSendToUart, this) + mUartSendTask(sIp6->mTaskletScheduler, EncodeAndSendToUart, this) { mState = kStartingFrame;