libcopp  1.1.0
standard_int_id_allocator.h
Go to the documentation of this file.
1 /*
2  * standard_int_id_allocator.h
3  *
4  * Created on: 2014年4月1日
5  * Author: owent
6  *
7  * Released under the MIT license
8  */
9 
10 #ifndef COTASK_CORE_STANDARD_INT_ID_ALLOCATOR_H
11 #define COTASK_CORE_STANDARD_INT_ID_ALLOCATOR_H
12 
13 #pragma once
14 
15 #include <ctime>
16 #include <stdint.h>
17 
18 
21 
22 namespace cotask {
23  namespace core {
24 
30  template <typename TKey = uint64_t>
32  public:
35 
36  static const value_type npos = 0;
37  public:
38  value_type allocate() UTIL_CONFIG_NOEXCEPT {
39  static util::lock::atomic_int_type<value_type> seq_alloc(255);
40 
41  static const size_t seq_bits = sizeof(value_type) * 4;
42  static const value_type time_mask = (static_cast<value_type>(1) << (sizeof(value_type) * 8 - seq_bits)) - 1;
43 
44  // always do not allocate 0 as a valid ID
45  value_type ret = npos;
46  while (npos == ret) {
47  value_type res = seq_alloc.load();
48  value_type time_part = res >> seq_bits;
49 
50  value_type next_ret = res + 1;
51  value_type next_time_part = next_ret >> seq_bits;
52  if (0 == time_part || time_part != next_time_part) {
53  value_type now_time = time_part;
54  while (time_part == now_time) {
55  now_time = static_cast<value_type>(time(NULL)) & time_mask;
56  }
57 
58  // if failed, maybe another thread do it
59  if (seq_alloc.compare_exchange_strong(res, now_time << seq_bits, util::lock::memory_order_acq_rel,
61  ret = now_time << seq_bits;
62  }
63  } else {
64  if (seq_alloc.compare_exchange_weak(res, next_ret, util::lock::memory_order_acq_rel,
66  ret = next_ret;
67  }
68  }
69  }
70 
71  return ret;
72  }
73 
74  void deallocate(value_type) UTIL_CONFIG_NOEXCEPT {}
75  };
76  }
77 }
78 
79 #endif /* STANDARD_INT_ID_ALLOCATOR_H_ */
value_type allocate() UTIL_CONFIG_NOEXCEPT
bool compare_exchange_strong(value_type &expected, value_type desired,::util::lock::memory_order success,::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
bool compare_exchange_weak(value_type &expected, value_type desired,::util::lock::memory_order success,::util::lock::memory_order failure) UTIL_CONFIG_NOEXCEPT
整数类型的原子操作跨平台适配 Licensed under the MIT licenses.
void deallocate(value_type) UTIL_CONFIG_NOEXCEPT
value_type load(::util::lock::memory_order order=::util::lock::memory_order_seq_cst) const UTIL_CONFIG_NOEXCEPT
cotask::impl::id_allocator< TKey > base_type