1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  Original Author: Stuart Swan, Cadence Design Systems, Inc., 2002-10-22
23
24 *****************************************************************************/
25
26/*****************************************************************************
27
28  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
29  changes you are making here.
30
31      Name, Affiliation, Date:
32  Description of Modification:
33
34 *****************************************************************************/
35// $Log: test01.cpp,v $
36// Revision 1.3  2011/02/08 06:49:37  acg
37//  Andy Goodrich: removed carriage returns.
38//
39// Revision 1.2  2011/02/01 17:17:37  acg
40//  Andy Goodrich: update of copyright notice, added visible CVS logging.
41//
42
43#define SC_INCLUDE_DYNAMIC_PROCESSES
44#include <systemc.h>
45
46
47int test_function(double d)
48{
49  cout << endl << sc_time_stamp() << ": " << sc_get_current_process_handle().name()
50       << ": Test_function sees " << d << endl;
51  return int(d);
52}
53
54void void_function(double d)
55{
56  cout << endl << sc_time_stamp() << ": " << sc_get_current_process_handle().name()
57       << ": void_function sees " << d << endl;
58}
59
60int ref_function(const double& d)
61{
62  cout << endl << sc_time_stamp() << ": " << sc_get_current_process_handle().name()
63       << ": ref_function sees " << d << endl;
64  return int(d);
65}
66
67
68class top : public sc_module
69{
70public:
71  SC_HAS_PROCESS(top);
72
73  top(sc_module_name name) : sc_module(name)
74  {
75     SC_THREAD(main);
76  }
77
78  void main()
79  {
80    int r;
81    sc_event e1, e2, e3, e4;
82
83    cout << endl;
84
85    e1.notify(100, SC_NS);
86
87    // Spawn several threads that co-operatively execute in round robin order
88
89    SC_FORK
90      sc_spawn(&r,
91        sc_bind(&top::round_robin, this, "1", sc_ref(e1), sc_ref(e2), 3), "t1") ,
92      sc_spawn(&r,
93        sc_bind(&top::round_robin, this, "2", sc_ref(e2), sc_ref(e3), 3), "t2") ,
94      sc_spawn(&r,
95        sc_bind(&top::round_robin, this, "3", sc_ref(e3), sc_ref(e4), 3), "t3") ,
96      sc_spawn(&r,
97        sc_bind(&top::round_robin, this, "4", sc_ref(e4), sc_ref(e1), 3), "t4") ,
98    SC_JOIN
99
100    cout << "Returned int is " << r << endl;
101    cout << endl << endl;
102
103    // Test that threads in thread pool are successfully reused ...
104
105    for (int i = 0 ; i < 10; i++)
106      sc_spawn(&r, sc_bind(&top::wait_and_end, this, i));
107
108    wait(20, SC_NS);
109
110    // Test thread reuse
111
112    for (int i = 0 ; i < 10; i++)
113      sc_spawn(&r, sc_bind(&top::wait_and_end, this, i));
114
115    wait(20, SC_NS);
116
117    // Demo of a function rather than method call, & use return value ...
118
119    wait( sc_spawn(&r, sc_bind(&test_function, 3.14159)).terminated_event() );
120
121    cout << "Returned int is " << r << endl;
122
123    // demo sc_spawn_options usage
124
125    sc_spawn_options ops;
126    ops.set_stack_size(0);
127    sc_process_handle handle1 = sc_spawn(
128      sc_bind(&void_function, 1.2345), "void_function", &ops
129    );
130    wait(handle1.terminated_event());
131
132    double d = 9.8765;
133    wait( sc_spawn(&r, sc_bind(&ref_function, sc_cref(d))).terminated_event() );
134
135    cout << "Returned int is " << r << endl;
136
137    cout << endl << "Done." << endl;
138  }
139
140  int round_robin(const char *str, sc_event& receive, sc_event& send, int cnt)
141  {
142    while (--cnt >= 0)
143    {
144      wait(receive);
145      cout << sc_time_stamp() << ": " << sc_get_current_process_handle().name()
146           << ": Round robin thread " << str << endl;
147      wait(10, SC_NS);
148      send.notify();
149    }
150
151    return 0;
152  }
153
154  int wait_and_end(int i)
155  {
156    wait( i + 1, SC_NS);
157    cout << sc_time_stamp() << ": " << sc_get_current_process_handle().name()
158         << ": Thread " << i << " ending." << endl;
159    return 0;
160  }
161};
162
163int sc_main (int argc , char *argv[])
164{
165  top top1("Top1");
166  sc_start();
167
168  return 0;
169}
170