📄 rtcosscheduling_pcp_manager.cpp
字号:
/* -*- C++ -*- */
//=============================================================================
/**
* @file RTCosScheduling_PCP_Manager.cpp
*
* RTCosScheduling_PCP_Manager.cpp,v 1.6 2003/12/30 05:03:10 dhinton Exp
*
* @author Matt Murphy <murphym@cs.uri.edu>
*/
//=============================================================================
#include "RTCosScheduling_PCP_Manager.h"
#include "ace/Condition_Thread_Mutex.h"
#include "ace/Thread.h"
#include "ace/OS_NS_stdio.h"
#if !defined (__ACE_INLINE__)
#include "RTCosScheduling_PCP_Manager.i"
#endif /* __ACE_INLINE__ */
namespace TAO {
struct
CosSchedulingLockNode *CosSchedulingLockNode::next()
{
/// INT_MAX is a special value indicating the end of a list
if (this->next_offset_ == INT_MAX)
{
return 0;
}
else
{
return ACE_reinterpret_cast(CosSchedulingLockNode *,
(ACE_reinterpret_cast(int, this) + this->next_offset_)
);
}
}
void
CosSchedulingLockNode::next(struct CosSchedulingLockNode *next_lock)
{
/// INT_MAX is a special value indicating the end of a list
if (next_lock == 0)
{
this->next_offset_ = INT_MAX;
}
else
{
this->next_offset_ =
(ACE_reinterpret_cast(int, next_lock) -
ACE_reinterpret_cast(int, this));
}
}
const CosSchedulingLockNode& CosSchedulingLockNode::operator=(const CosSchedulingLockNode& L)
{
this->threadID_ = L.threadID_;
this->priority_ceiling_ = L.priority_ceiling_;
this->priority_ = L.priority_;
this->elevated_priority_ = L.elevated_priority_;
return *this;
}
CosSchedulingLockList::CosSchedulingLockList(CosSchedulingLockNode *lock_array,
int size,
ACE_SYNCH_MUTEX *mutex)
{
ACE_TRY_NEW_ENV
{
/*
* The pointers to the beginnings of the lists must be globally visible,
* so I have chosen to use the first three locks in the array.
* lock_array[0].next() (== free_->next() ) -> start of free list
* lock_array[1].next() (== granted_->next()) -> start of granted list
* lock_array[2].next() (== pending_->next()) -> start of pending list
*/
/// start of the free list
lock_array[0].next(&lock_array[3]);
/// start with an empty granted list
lock_array[1].next(0);
/// start with an empty pending list
lock_array[2].next(0);
/// initialize the free list (link together the elements in the array)
for (int i = 3; i < (size - 1); ++i)
{
lock_array[i].next(&lock_array[i + 1]);
ACE_NEW_THROW_EX(lock_array[i].condition_,
ACE_SYNCH_CONDITION(*mutex),
CORBA::NO_MEMORY());
}
ACE_TRY_CHECK;
lock_array[size - 1].next(0); /// terminate the free list
/// Update the positions
this->free_ = &lock_array[0];
this->granted_ = &lock_array[1];
this->pending_ = &lock_array[2];
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION,
"Error in generating Locklist on ServerScheduler\n");
}
ACE_ENDTRY;
}
void
CosSchedulingLockList::destroy(int size)
{
for (int i = 3; i < size; ++i)
{
this->free_[i].condition_->remove();
delete &free_[i].condition_;
}
}
int
CosSchedulingLockList::grant_lock(const CosSchedulingLockNode& L)
{
if (this->free_->next() == 0)
{
return 0; /// no free nodes left
}
/// take a node from the free list
CosSchedulingLockNode *new_lock = this->free_->next();
this->free_->next(this->free_->next()->next());
*new_lock = L;
if ((this->granted_->next() == 0)
|| (this->granted_->next()->priority_ceiling_ <= L.priority_ceiling_))
{
/// insert at the head of the list
new_lock->next(this->granted_->next());
this->granted_->next(new_lock);
}
else
{
/// find the proper location to insert
/// the new lock (ordered by priority ceiling)
CosSchedulingLockNode *current_lock = granted_->next();
while ((current_lock->next() != 0)
&& (current_lock->next()->priority_ceiling_ > L.priority_ceiling_))
{
current_lock = current_lock->next();
}
new_lock->next(current_lock->next());
current_lock->next(new_lock);
}
return 1;
}
int
CosSchedulingLockList::defer_lock(const CosSchedulingLockNode& L,
ACE_SYNCH_MUTEX & mutex)
{
if (this->free_->next() == 0)
{
return 0; /// no free nodes left
}
CosSchedulingLockNode *new_lock = free_->next();
this->free_->next(free_->next()->next());
*new_lock = L;
if ((this->pending_->next() == 0)
||(this->pending_->next()->priority_ <= L.priority_))
{
/// insert at the head of the list
new_lock->next(this->pending_->next());
this->pending_->next(new_lock);
}
else
{
/// find the proper location to insert the new lock
CosSchedulingLockNode *current_lock = pending_->next();
while ((current_lock->next() != 0)
&& (current_lock->next()->priority_ceiling_ > L.priority_ceiling_))
{
current_lock = current_lock->next();
}
new_lock->next(current_lock->next());
current_lock->next(new_lock);
}
if (new_lock->condition_)
{
new_lock->condition_->wait(mutex);
return 1;
}
else
{
return 0;
}
}
int
CosSchedulingLockList::release_lock(CosSchedulingLockNode& L)
{
if (this->granted_->next() == 0)
{
return 0; /// empty list of granted locks
}
if (this->granted_->next()->threadID_ == L.threadID_)
{
/// remove the lock at the head of the list and put it on the free list
/// Set the Lock to the next one in the granted list
L = *(this->granted_->next());
/// (sets next offset from previous statement)
L.next(this->granted_->next()->next());
/// set the next granted's next one to be the next free one
this->granted_->next()->next(this->free_->next());
/// Set the next free one to be the next granted one
this->free_->next(this->granted_->next());
/// Set the next granted on to be the Lock's next one
this->granted_->next(L.next());
/// Set the Locks next on to NULL
L.next(0);
return 1;
}
/// find the lock to remove
CosSchedulingLockNode *current_lock = granted_->next();
while ((current_lock->next() != 0)
&& (current_lock->next()->threadID_ != L.threadID_))
{
current_lock = current_lock->next();
}
if (current_lock->next() != 0)
{
/// removes lock and prepends to the free list, as above
L = *(current_lock->next());
L.next(current_lock->next()->next());
current_lock->next()->next(this->free_->next());
this->free_->next(current_lock->next());
current_lock->next(L.next());
L.next(0);
return 1;
}
return 0;
}
int
CosSchedulingLockList::remove_deferred_lock(CosSchedulingLockNode& L)
{
if (this->pending_->next() == 0)
{
return 0; /// empty list of pending locks
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -