Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5134 serge 1
// thread -*- C++ -*-
2
 
3
// Copyright (C) 2008-2013 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
 
26
#include 
27
#include 
28
#include 
29
#include 
30
 
31
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
32
 
33
#if defined(_GLIBCXX_USE_GET_NPROCS)
34
# include 
35
# define _GLIBCXX_NPROCS get_nprocs()
36
#elif defined(_GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP)
37
# define _GLIBCXX_NPROCS pthread_num_processors_np()
38
#elif defined(_GLIBCXX_USE_SYSCTL_HW_NCPU)
39
# include 
40
# include 
41
static inline int get_nprocs()
42
{
43
 int count;
44
 size_t size = sizeof(count);
45
 int mib[] = { CTL_HW, HW_NCPU };
46
 if (!sysctl(mib, 2, &count, &size, NULL, 0))
47
   return count;
48
 return 0;
49
}
50
# define _GLIBCXX_NPROCS get_nprocs()
51
#elif defined(_GLIBCXX_USE_SC_NPROCESSORS_ONLN)
52
# include 
53
# define _GLIBCXX_NPROCS sysconf(_SC_NPROCESSORS_ONLN)
54
#elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)
55
# include 
56
# define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN)
57
#else
58
# define _GLIBCXX_NPROCS 0
59
#endif
60
 
61
#ifndef _GLIBCXX_USE_NANOSLEEP
62
# ifdef _GLIBCXX_HAVE_SLEEP
63
#  include 
64
# elif defined(_GLIBCXX_HAVE_WIN32_SLEEP)
65
#  include 
66
# else
67
#  error "No sleep function known for this target"
68
# endif
69
#endif
70
 
71
namespace std _GLIBCXX_VISIBILITY(default)
72
{
73
  namespace
74
  {
75
    extern "C" void*
76
    execute_native_thread_routine(void* __p)
77
    {
78
      thread::_Impl_base* __t = static_cast(__p);
79
      thread::__shared_base_type __local;
80
      __local.swap(__t->_M_this_ptr);
81
 
82
      __try
83
	{
84
	  __t->_M_run();
85
	}
86
      __catch(const __cxxabiv1::__forced_unwind&)
87
	{
88
	  __throw_exception_again;
89
	}
90
      __catch(...)
91
	{
92
	  std::terminate();
93
	}
94
 
95
      return 0;
96
    }
97
  }
98
 
99
_GLIBCXX_BEGIN_NAMESPACE_VERSION
100
 
101
  void
102
  thread::join()
103
  {
104
    int __e = EINVAL;
105
 
106
    if (_M_id != id())
107
      __e = __gthread_join(_M_id._M_thread, 0);
108
 
109
    if (__e)
110
      __throw_system_error(__e);
111
 
112
    _M_id = id();
113
  }
114
 
115
  void
116
  thread::detach()
117
  {
118
    int __e = EINVAL;
119
 
120
    if (_M_id != id())
121
      __e = __gthread_detach(_M_id._M_thread);
122
 
123
    if (__e)
124
      __throw_system_error(__e);
125
 
126
    _M_id = id();
127
  }
128
 
129
  void
130
  thread::_M_start_thread(__shared_base_type __b)
131
  {
132
    if (!__gthread_active_p())
133
#if __EXCEPTIONS
134
      throw system_error(make_error_code(errc::operation_not_permitted),
135
			 "Enable multithreading to use std::thread");
136
#else
137
      __throw_system_error(int(errc::operation_not_permitted));
138
#endif
139
 
140
    __b->_M_this_ptr = __b;
141
    int __e = __gthread_create(&_M_id._M_thread,
142
			       &execute_native_thread_routine, __b.get());
143
    if (__e)
144
    {
145
      __b->_M_this_ptr.reset();
146
      __throw_system_error(__e);
147
    }
148
  }
149
 
150
  unsigned int
151
  thread::hardware_concurrency() noexcept
152
  {
153
    int __n = _GLIBCXX_NPROCS;
154
    if (__n < 0)
155
      __n = 0;
156
    return __n;
157
  }
158
 
159
_GLIBCXX_END_NAMESPACE_VERSION
160
 
161
namespace this_thread
162
{
163
_GLIBCXX_BEGIN_NAMESPACE_VERSION
164
 
165
  void
166
  __sleep_for(chrono::seconds __s, chrono::nanoseconds __ns)
167
  {
168
#ifdef _GLIBCXX_USE_NANOSLEEP
169
    __gthread_time_t __ts =
170
      {
171
	static_cast(__s.count()),
172
	static_cast(__ns.count())
173
      };
174
    ::nanosleep(&__ts, 0);
175
#elif defined(_GLIBCXX_HAVE_SLEEP)
176
# ifdef _GLIBCXX_HAVE_USLEEP
177
    ::sleep(__s.count());
178
    if (__ns.count() > 0)
179
      {
180
        long __us = __ns.count() / 1000;
181
        if (__us == 0)
182
          __us = 1;
183
        ::usleep(__us);
184
      }
185
# else
186
    ::sleep(__s.count() + (__ns >= 1000000));
187
# endif
188
#elif defined(_GLIBCXX_HAVE_WIN32_SLEEP)
189
    unsigned long ms = __ns.count() / 1000000;
190
    if (__ns.count() > 0 && ms == 0)
191
      ms = 1;
192
    ::Sleep(chrono::milliseconds(__s).count() + ms);
193
#endif
194
  }
195
 
196
_GLIBCXX_END_NAMESPACE_VERSION
197
}
198
 
199
} // namespace std
200
 
201
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1