scx_mutex_w_policy.cpp from GreenSocs at Krugle
Show scx_mutex_w_policy.cpp syntax highlighted
//****************************************************************************
//****************************************************************************
//
// Copyright (c) 2002 Thorsten Groetker, Stan Liao, Grant Martin, Stuart Swan
//
// Permission is hereby granted to use, modify, and distribute this source
// code in any way as long as this entire copyright notice is retained
// in unmodified form within the source code.
//
// This software is distributed on an "AS IS" basis, without warranty
// of any kind, either express or implied.
//
// This source code is from the book "System Design with SystemC".
// For detailed discussion on this example, see the relevant section
// within the "System Design with SystemC" book.
//
// To obtain the book and find additional source code downloads, etc., visit
// www.systemc.org
// Look in the "Products & Solutions" -> "SystemC Books". Then look at the
// entry for "System Design with SystemC".
//
//****************************************************************************
//****************************************************************************
// Specialization of sc_mutex to allow FIFO or true RANDOM
// arbitration policies when more than one process is
// contending for the mutex
//
// This mutex is also significantly more efficient than sc_mutex
// if there is a lot of actual contention for ownership of the mutex,
// since only the process that actually acquires the mutex is resumed.
//
// See section 7.4, page 120 of "System Design with SystemC" for
// additional discussion
#include <systemc.h>
class scx_mutex_w_policy : public sc_mutex
{
public:
enum policy_type { FIFO, RANDOM };
explicit scx_mutex_w_policy(policy_type policy) : policy_(policy) {}
virtual int lock()
{
if (in_use()) {
sc_event my_event;
event_list.push_back(&my_event);
wait(my_event);
}
m_owner = sc_get_curr_process_handle();
return 0;
}
virtual int unlock()
{
if (m_owner != sc_get_curr_process_handle()) return -1;
m_owner = 0;
sc_event* e = next_event();
if (e) e->notify();
return 0;
}
private:
sc_event* next_event()
{
if (event_list.empty())
return 0;
if (policy_ == FIFO)
{
return event_list.pop_front();
}
else
{ // RANDOM
sc_plist_iter<sc_event*> ev_itr(&event_list);
int index = rand() % event_list.size();
for (int i = 0; i < index; i++)
ev_itr++;
sc_event* e = ev_itr.get();
ev_itr.remove();
return e;
}
}
sc_plist<sc_event*> event_list;
policy_type policy_;
};
class top : public sc_module
{
public:
SC_HAS_PROCESS(top);
top(sc_module_name name) : mutex_(scx_mutex_w_policy::FIFO)
{
SC_THREAD(t1);
SC_THREAD(t2);
SC_THREAD(t3);
}
void t1() {
wait(1, SC_NS);
mutex_.lock();
cout << "t1 got mutex at " << sc_time_stamp() << endl;
wait(10, SC_NS);
mutex_.unlock();
}
void t2() {
wait(2, SC_NS);
mutex_.lock();
cout << "t2 got mutex at " << sc_time_stamp() << endl;
wait(10, SC_NS);
mutex_.unlock();
}
void t3() {
wait(3, SC_NS);
mutex_.lock();
cout << "t3 got mutex at " << sc_time_stamp() << endl;
wait(10, SC_NS);
mutex_.unlock();
}
private:
scx_mutex_w_policy mutex_;
};
int sc_main (int argc , char *argv[])
{
top top1("Top1");
sc_start(1000, SC_NS);
cout << endl << endl;
return 0;
}
See more files for this project here
To develop SystemC infrustructure, basic IP, patches and add on library code for eventual standerdization.\r\nThe GreenSocs project is made up of a number of contributions (sub projects). Please visit www.greensocs.com for more information.
Project homepage:
http://sourceforge.net/projects/greensocs
Programming language(s): C,C++,Java,Perl,XML
License: other
Makefile.am
scx_mutex_w_policy.cpp
scx_mutex_w_policy.dsp
scx_mutex_w_policy.dsw
scx_mutex_w_policy.vcproj