sync.hpp kernel.hpp cstdint tk::Semaphore tk::Mutex tk::LockGuard tk #pragmaonce #include"kernel.hpp" #include<cstdint> namespacetk{ classSemaphore{ public: explicitSemaphore(int32_tinitial_count=1,int32_tmax_count=1) :count_(initial_count),max_count_(max_count){} voidacquire(){ uint32_tsave=detail::sched_lock(); while(count_<=0){ uint8_tslot=detail::current_task_slot(); wait_mask_|=(task_mask_t{1}<<slot); detail::block_current_task_locked(); detail::sched_unlock(save); //他タスクからrelease()されて再開したら再チェック save=detail::sched_lock(); } count_--; detail::sched_unlock(save); } booltry_acquire(){ uint32_tsave=detail::sched_lock(); boolsuccess=false; if(count_>0){ count_--; success=true; } detail::sched_unlock(save); returnsuccess; } voidrelease(){ uint32_tsave=detail::sched_lock(); if(count_<max_count_){ count_++; } if(wait_mask_!=0){ uint8_tslot=detail::find_highest_prio_waiter(wait_mask_); if(slot!=0xFF){ wait_mask_&=~(task_mask_t{1}<<slot); detail::wake_task_locked(TaskHandle{slot}); } } detail::sched_unlock(save); } int32_tcount()const{ uint32_tsave=detail::sched_lock(); int32_tc=count_; detail::sched_unlock(save); returnc; } private: int32_tcount_; int32_tmax_count_; task_mask_twait_mask_{0}; }; usingBinarySemaphore=Semaphore; classMutex{ public: Mutex()=default; voidlock(){ uint32_tsave=detail::sched_lock(); uint8_tmy_slot=detail::current_task_slot(); while(locked_){ wait_mask_|=(task_mask_t{1}<<my_slot); detail::block_current_task_locked(); detail::sched_unlock(save); save=detail::sched_lock(); } locked_=true; owner_slot_=my_slot; detail::sched_unlock(save); } booltry_lock(){ uint32_tsave=detail::sched_lock(); uint8_tmy_slot=detail::current_task_slot(); boolsuccess=false; if(!locked_){ locked_=true; owner_slot_=my_slot; success=true; } detail::sched_unlock(save); returnsuccess; } voidunlock(){ uint32_tsave=detail::sched_lock(); uint8_tmy_slot=detail::current_task_slot(); if(locked_&&owner_slot_==my_slot){ locked_=false; owner_slot_=0xFF; if(wait_mask_!=0){ uint8_tslot=detail::find_highest_prio_waiter(wait_mask_); if(slot!=0xFF){ wait_mask_&=~(task_mask_t{1}<<slot); detail::wake_task_locked(TaskHandle{slot}); } } } detail::sched_unlock(save); } boolis_locked()const{ uint32_tsave=detail::sched_lock(); boollk=locked_; detail::sched_unlock(save); returnlk; } private: boollocked_{false}; uint8_towner_slot_{0xFF}; task_mask_twait_mask_{0}; }; template<typenameLockable> classLockGuard{ public: explicitLockGuard(Lockable&m):m_(m){m_.lock();} ~LockGuard(){m_.unlock();} LockGuard(constLockGuard&)=delete; LockGuard&operator=(constLockGuard&)=delete; private: Lockable&m_; }; }//namespacetk