summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Random.cpp
blob: 2e85283e384035ffbe9cef6c55eef1180113e986 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// -*- C++ -*-

#include "orbsvcs/LoadBalancing/LB_Random.h"

#include "tao/ORB_Constants.h"
#include "ace/OS_NS_time.h"
#include "ace/os_include/os_netdb.h"

ACE_RCSID (LoadBalancing,
           LB_Random,
           "$Id$")

#ifdef ACE_HAS_PTHREADS_STD
static pthread_once_t tao_lb_once_control = PTHREAD_ONCE_INIT;
#endif  /* ACE_HAS_PTHREADS_STD */

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

extern "C" void tao_lb_random_init_routine (void)
{
  ACE_OS::srand (static_cast<unsigned int> (ACE_OS::time ()));
}

TAO_LB_Random::TAO_LB_Random (PortableServer::POA_ptr poa)
  : poa_ (PortableServer::POA::_duplicate (poa))
{
  TAO_LB_Random::init ();
}

char *
TAO_LB_Random::name (void)
{
  return CORBA::string_dup ("Random");
}

CosLoadBalancing::Properties *
TAO_LB_Random::get_properties (void)
{
  CosLoadBalancing::Properties * props = 0;
  ACE_NEW_THROW_EX (props,
                    CosLoadBalancing::Properties,
                    CORBA::NO_MEMORY (
                      CORBA::SystemException::_tao_minor_code (
                        TAO::VMCID,
                        ENOMEM),
                      CORBA::COMPLETED_NO));

  return props;
}

void
TAO_LB_Random::push_loads (
    const PortableGroup::Location & /* the_location */,
    const CosLoadBalancing::LoadList & /* loads */)
{
  throw CosLoadBalancing::StrategyNotAdaptive ();
}

CosLoadBalancing::LoadList *
TAO_LB_Random::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
                          const PortableGroup::Location & the_location)
{
  if (CORBA::is_nil (load_manager))
    throw CORBA::BAD_PARAM ();

  return load_manager->get_loads (the_location);
}

CORBA::Object_ptr
TAO_LB_Random::next_member (
    PortableGroup::ObjectGroup_ptr object_group,
    CosLoadBalancing::LoadManager_ptr load_manager)
{
  if (CORBA::is_nil (load_manager))
    throw CORBA::BAD_PARAM ();

  PortableGroup::Locations_var locations =
    load_manager->locations_of_members (object_group);

  return TAO_LB_Random::_tao_next_member (object_group,
                                          load_manager,
                                          locations.in ());
}

void
TAO_LB_Random::analyze_loads (
    PortableGroup::ObjectGroup_ptr /* object_group */,
    CosLoadBalancing::LoadManager_ptr /* load_manager */)
{
}

PortableServer::POA_ptr
TAO_LB_Random::_default_POA (void)
{
  return PortableServer::POA::_duplicate (this->poa_.in ());
}

CORBA::Object_ptr
TAO_LB_Random::_tao_next_member (
    PortableGroup::ObjectGroup_ptr object_group,
    CosLoadBalancing::LoadManager_ptr load_manager,
    const PortableGroup::Locations & locations)
{
  const CORBA::ULong len = locations.length ();
  if (len == 0)
    throw CORBA::TRANSIENT ();

  // Pick a random location in the sequence using the higher order
  // bits (zero based indexing).
  //
  // See Numerical Recipes in C: The Art of Scientific Computing
  // (William  H.  Press, Brian P. Flannery, Saul A. Teukolsky,
  // William T.  Vetterling;  New  York:  Cambridge University Press,
  // 1992 (2nd ed., p. 277)) for details on why using the lower order
  // bits, as in (rand() % 10), is bad.  In particular, the lower
  // order bits in older rand() implementations may not be as random
  // as the higher order bits.
  //
  // @todo It would be better to use the random() function since it
  //       is supposed to have a larger period than rand(), in
  //       addition to the fact that the lower order bits should be as
  //       random as the higher order bits.

  // Prevent integer arithmetic overflow.
  const CORBA::Float flen = static_cast<CORBA::Float> (len);

  const CORBA::ULong i =
    static_cast<CORBA::ULong> (flen * ACE_OS::rand () / (RAND_MAX + 1.0));

  ACE_ASSERT (i < len);

//   ACE_DEBUG ((LM_DEBUG,
//               "** Len = %u\t"
//               "Location # %u\t"
//               "Loc Name = \"%s\"\n",
//               len,
//               i,
//               locations[i][0].id.in ()));

  return load_manager->get_member_ref (object_group,
                                       locations[i]);
}

void
TAO_LB_Random::init (void)
{
#ifdef ACE_HAS_PTHREADS_STD
  (void) ::pthread_once (&::tao_lb_once_control,
                         ::tao_lb_random_init_routine);
#else
  ::tao_lb_random_init_routine ();
#endif  /* ACE_HAS_PTHREADS_STD */
}

TAO_END_VERSIONED_NAMESPACE_DECL