17#if __cplusplus >= 201100
18#define HAVE_CPP_THREADS
21#undef HAVE_CPP_THREADS
100#ifdef HAVE_CPP_THREADS
101 std::atomic_flag _lock;
102 short _owner, _head, _tail;
107#ifdef HAVE_CPP_THREADS
115#ifdef HAVE_CPP_THREADS
120 _owner = other._owner;
140 struct flock &lock_info,
size_t offset,
size_t len,
bool lock);
170#ifdef HAVE_CPP_THREADS
211 return (
prev & 3) != 1;
215 return (
int)
data[0];
240 return block->is_free();
243 return (
void *) (
base + addr);
306#ifdef HAVE_CPP_THREADS
308 std::atomic<ptrdiff_t>
rc;
313 return (ptrdiff_t)
rc;
317 return (ptrdiff_t)
rc;
356 return addr ^ (1 <<
level);
363 char *addr = (
char *) ptr -
sizeof(
Block);
367 size_t offset = (
unsigned char *) ptr - segstart;
432 operator bool()
const {
463 template <
typename U>
493 operator bool()
const {
518 template <
typename U>
553 for (
size_t i = 0;
i < n;
i++) {
565template <
typename T,
typename Arg>
572template <
typename T,
typename Arg1,
typename Arg2>
575 new (
result.to_ptr())
T(arg1, arg2);
579template <
typename T,
typename Arg1,
typename Arg2,
typename Arg3>
582 new (
result.to_ptr())
T(arg1, arg2, arg3);
586template <
typename T,
typename Arg1,
typename Arg2,
typename Arg3,
590 new (
result.to_ptr())
T(arg1, arg2, arg3, arg4);
594template <
typename T,
typename Arg1,
typename Arg2,
typename Arg3,
595 typename Arg4,
typename Arg5>
596VRef<T> vnew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
598 new (
result.to_ptr())
T(arg1, arg2, arg3, arg4, arg5);
607#if __cplusplus >= 201100
651 template <
typename U>
696 for (
size_t i = 0;
i < n;
i++) {
708template <
typename T,
typename Arg>
715template <
typename T,
typename Arg1,
typename Arg2>
718 new (
result.to_ptr())
T(arg1, arg2);
722template <
typename T,
typename Arg1,
typename Arg2,
typename Arg3>
725 new (
result.to_ptr())
T(arg1, arg2, arg3);
737 _buffer = vnew_uninitialized_array<char>(
_len + 1);
742 _buffer = vnew_uninitialized_array<char>(
len + 1);
743 char *buffer =
_buffer.as_ptr();
744 memcpy(buffer,
s,
len);
749 _buffer = vnew_uninitialized_array<char>(
len + 1);
767 return vnew<VString>(
s);
771 return vnew<VString>(
s, len);
775 return vnew<VString>(len);
779template <
typename Spec>
782 typedef typename Spec::Key
K;
783 typedef typename Spec::Value
V;
805 bool replace =
true);
809 return add(key, value, oldkey, oldvalue, replace);
815 return remove(key, oldkey, oldvalue);
820 if (
find(key, value))
827template <
typename Spec>
829 using namespace internals;
831 while (_nbuckets <
size)
833 _buckets = vnew_array<VRef<Node> >(_nbuckets);
834 _locks = vnew_uninitialized_array<FastLock>(_nbuckets);
835 for (
size_t i = 0;
i < _nbuckets;
i++)
840template <
typename Spec>
842 for (
size_t b = 0;
b < _nbuckets;
b++) {
848 Spec::free_key(node_ptr->
key);
849 Spec::free_value(node_ptr->
value);
859template <
typename Spec>
861 VRef<V> &oldvalue,
bool replace) {
862 size_t hash = Spec::hash(key.
as_ptr());
863 size_t b = hash & (_nbuckets - 1);
869 if (hash == node_ptr->
hash
871 value = node_ptr->
value;
872 if (!
last.is_null()) {
875 node_ptr->
next = _buckets[
b];
878 oldkey = node_ptr->
key;
879 oldvalue = node_ptr->
value;
882 node_ptr->
value = value;
892 node_ptr->
hash = hash;
894 node_ptr->
value = value;
895 node_ptr->
next = _buckets[
b];
903template <
typename Spec>
905 size_t hash = Spec::hash(key.
as_ptr());
906 size_t b = hash & (_nbuckets - 1);
912 if (hash == node_ptr->
hash
914 oldkey = node_ptr->
key;
915 oldvalue = node_ptr->
value;
917 if (
last.is_null()) {
918 _buckets[
b] = node_ptr->
next;
932template <
typename Spec>
934 size_t hash = Spec::hash(key.
as_ptr());
935 size_t b = hash & (_nbuckets - 1);
941 if (hash == node_ptr->
hash
943 value = node_ptr->
value;
945 if (!
last.is_null()) {
947 node_ptr->
next = _buckets[
b];
965 size_t len =
s->len();
966 const char *
str =
s->str();
968 for (
size_t i = 0;
i < len;
i++) {
974 if (s1->
len() != s2->
len())
976 size_t len = s1->
len();
977 const char *str1 = s1->
str(), *str2 = s2->
str();
978 for (
size_t i = 0;
i < len;
i++) {
979 if (str1[
i] != str2[
i])
1002#ifdef HAVE_CPP_THREADS
1027 template <
typename T>
1044template <
typename T>
1058 if (
_head->next.is_null()) {
1066 node->next = vnull<Node>();
1067 if (
_tail.is_null()) {
1074 template <
typename U>
1076 template <
typename U>
1133template <
typename T>
1140 template <
typename U>
1154template <
typename T>
1162 if (_sem.is_null()) {
1163 _sem = vnew<Semaphore>();
1165 bool result = _sem->start_wait(sig);
1170template <
typename T>
1173 if (!_sem.is_null()) {
1181template <
typename T>
1188 if (_sem.is_null()) {
1189 _sem = vnew<Semaphore>();
1198 _sem->start_wait(0);
1206 _sem = vnull<Semaphore>();
1212template <
typename T>
1220template <
typename T>
1274 return _sem->start_wait(sig);
1283template <
typename T>
1292 return _queue->_outgoing.start_wait(sig);
1295 _queue->_outgoing.stop_wait();
1298 _queue->enqueue_nowait(item);
1302template <
typename T>
1311 return _queue->_incoming.start_wait(sig);
1314 _queue->_incoming.stop_wait();
1317 return _queue->dequeue_nowait();
1321template <
typename T>
static CanonicalForm bound(const CFMatrix &M)
DequeueEvent(VRef< Queue< T > > queue)
VRef< Queue< T > > _queue
virtual void stop_listen()
virtual bool start_listen(internals::ipc_signal_t sig)
virtual void stop_listen()
VRef< Queue< T > > _queue
virtual bool start_listen(internals::ipc_signal_t sig)
EnqueueEvent(VRef< Queue< T > > queue)
EventSet & operator<<(Event &event)
EventSet & operator<<(Event *event)
virtual void stop_listen()=0
virtual bool start_listen(internals::ipc_signal_t sig)=0
Result< T > try_dequeue()
void push(VRef< Node > node)
void enqueue_nowait(T item)
int _waiting[internals::MAX_PROCESS+1]
bool start_wait(internals::ipc_signal_t sig=0)
internals::ipc_signal_t _signals[internals::MAX_PROCESS+1]
Semaphore(size_t value=0)
virtual bool start_listen(internals::ipc_signal_t sig)
SyncReadEvent(VRef< SyncVar< T > > syncvar)
virtual void stop_listen()
VRef< SyncVar< T > > _syncvar
bool start_wait(internals::ipc_signal_t sig)
bool remove(VRef< K > key, VRef< K > &oldkey, VRef< V > &oldvalue)
bool find(VRef< K > key, VRef< V > &value)
void _lock_bucket(size_t b)
VRef< V > find(VRef< K > key)
bool remove(VRef< K > key)
VRef< VRef< Node > > _buckets
bool add(VRef< K > key, VRef< V > value, bool replace=true)
bool add(VRef< K > key, VRef< V > value, VRef< K > &oldkey, VRef< V > &oldvalue, bool replace=true)
void _unlock_bucket(size_t b)
VRef< internals::FastLock > _locks
VString(const char *s, size_t len)
VRef< VString > clone() const
WaitSemaphoreEvent(VRef< Semaphore > sem)
virtual bool start_listen(internals::ipc_signal_t sig)
virtual void stop_listen()
FastLock(vaddr_t offset=0)
const CanonicalForm int s
const ExtensionInfo & info
< [in] sqrfree poly
void drop_pending_signals()
void init_flock_struct(struct flock &lock_info, size_t offset, size_t len, bool lock)
void lock_file(int fd, size_t offset, size_t len)
void vmem_free(vaddr_t vaddr)
Block * block_ptr(vaddr_t vaddr)
vaddr_t vmem_alloc(size_t size)
static vaddr_t allocated_ptr_to_vaddr(void *ptr)
static const size_t MAX_SEGMENTS
vaddr_t freelist[LOG2_SEGMENT_SIZE+1]
static const size_t SEGMENT_SIZE
static const size_t METABLOCK_SIZE
static const int LOG2_SEGMENT_SIZE
ipc_signal_t wait_signal(bool lock)
static const int LOG2_MAX_SEGMENTS
static const int MAX_PROCESS
ProcessInfo process_info[MAX_PROCESS]
static segaddr_t find_buddy(segaddr_t addr, int level)
ipc_signal_t check_signal(bool resume, bool lock)
void init_metapage(bool create)
void unlock_file(int fd, size_t offset, size_t len)
static const size_t SEGMENT_MASK
bool send_signal(int processno, ipc_signal_t sig, bool lock)
static int find_level(size_t size)
const segaddr_t SEGADDR_NULL
VRef< T > vnew_uninitialized_array(size_t n)
ZRef< T > znew_array(size_t n)
static void vmem_deinit()
ZRef< T > znew_uninitialized()
VRef< T > vnew_array(size_t n)
ZRef< T > znew_uninitialized_array(size_t n)
VRef< T > vnew_uninitialized()
static Status vmem_init()
static VRef< VString > vstring(const char *s)
internals::Mutex FastLock
static int index(p_Length length, p_Ord ord)
static void free_value(VRef< Value > value)
static bool equal(const VString *s1, const VString *s2)
static size_t hash(const VString *s)
static void free_key(VRef< Key > key)
bool operator!=(VRef< void > other)
VRef< void > & operator=(VRef< void > other)
bool operator==(VRef< void > other)
static VRef< void > from_vaddr(internals::vaddr_t vaddr)
VRef(internals::vaddr_t vaddr)
static VRef< void > alloc(size_t n=1)
VRef< T > & operator=(VRef< T > other)
static VRef< T > alloc(size_t n=1)
VRef(internals::vaddr_t vaddr)
bool operator!=(VRef< T > other)
static VRef< T > from_vaddr(internals::vaddr_t vaddr)
T & operator[](size_t index)
bool operator==(VRef< T > other)
internals::refcount_t & refcount()
ZRef(internals::vaddr_t vaddr)
ZRef< T > & operator=(ZRef< T > other)
static internals::vaddr_t alloc()
void mark_as_free(int level)
void mark_as_allocated(vaddr_t vaddr, int level)
void ensure_is_mapped(vaddr_t vaddr)
Block * block_ptr(vaddr_t vaddr)
size_t segment_no(vaddr_t vaddr)
void * mmap_segment(int seg)
VSeg segment(vaddr_t vaddr)
void * to_ptr(vaddr_t vaddr)
VSeg segments[MAX_SEGMENTS]
vaddr_t vaddr(size_t segno, segaddr_t addr)
segaddr_t segaddr(vaddr_t vaddr)
ProcessChannel channels[MAX_PROCESS]
Block * block_ptr(segaddr_t addr)
void * ptr(segaddr_t addr)
bool is_free(segaddr_t addr)
static void lock(vaddr_t vaddr)
ptrdiff_t dec(vaddr_t vaddr)
refcount_t(ptrdiff_t init)
ptrdiff_t inc(vaddr_t vaddr)
static void unlock(vaddr_t vaddr)