File: token.h

package info (click to toggle)
meshlab 2020.09%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 45,132 kB
  • sloc: cpp: 400,238; ansic: 31,952; javascript: 1,578; sh: 387; yacc: 238; lex: 139; python: 86; makefile: 30
file content (113 lines) | stat: -rw-r--r-- 3,461 bytes parent folder | download | duplicates (3)
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
#ifndef GCACHE_TOKEN_H
#define GCACHE_TOKEN_H

#include <wrap/system/multithreading/atomic_int.h>

/* QAtomic int count keep trak of token status:
   >0: locked (possibly multiple times)
   0: data ready in last cache
   -1: not in last cache
   -2: to removed from all caches
   -3: out of caches
   */

/** Holds the resources to be cached.
    The Priority template argument can simply be a floating point number
    or something more complex, (frame and error in pixel); the only
    requirement is the existence of a < comparison operator */
namespace vcg {

template <typename Priority>
class Token {
public:
    ///Resource loading status
    /*** - LOCKED: resource in the higher cache and locked
       - READY: resource in the higher cache
       - CACHE: resource in some cache (not the highest)
       - REMOVE: resource in some cache and scheduled for removal
       - OUTSIDE: resource not in the cache system */
    enum Status { LOCKED = 1, READY = 0, CACHE = -1, REMOVE = -2, OUTSIDE = -3 };
    ///Do not access these members directly. Will be moved to private shortly.
    ///used by various cache threads to sort objects [do not use, should be private]
    Priority priority;
    ///set in the main thread   [do not use, should be private]
    Priority new_priority;
    ///swap space used in updatePriorities [do not use, should be private]
    mt::atomicInt count;

public:
    Token(): count(OUTSIDE) {}

    ///the new priority will be effective only after a call to Controller::updatePriorities()
    void setPriority(const Priority &p) {
        new_priority = p;
    }

    //set and get are safe to call in the controller thread.
    Priority getPriority() {
        return new_priority;
    }

    ///return false if resource not in highest query. remember to unlock when done
    bool lock() {
        if(count.fetchAndAddAcquire(1) >= 0) return true;
        count.deref();
        return false;
    }

    ///assumes it was locked first and 1 unlock for each lock.
    bool unlock() {
        return count.deref();
    }

    ///can't be removed if locked and will return false
    bool remove() {
        count.testAndSetOrdered(READY, REMOVE);
        count.testAndSetOrdered(CACHE, REMOVE);
#if(QT_VERSION < 0x050000)
        return count <= REMOVE;
#else
        return count.load() <= REMOVE;                   //might have become OUSIDE in the meanwhile
#endif
    }

    bool isLocked() {
#if(QT_VERSION < 0x050000)
        return count > 0;
#else
        return count.load() > 0;
#endif
    }
    bool isInCache() { return count != OUTSIDE; }  //careful, can be used only when provider thread is locked.

    ///copy priority to swap space [do not use, should be private]
    void pushPriority() {
        priority = new_priority;
    }

    bool operator<(const Token &a) const {
#if(QT_VERSION < 0x050000)
        if(count == a.count)
            return priority < a.priority;
        return count < a.count;
#else
        if(count.load() == a.count.load())
            return priority < a.priority;
        return count.load() < a.count.load();
#endif
    }
    bool operator>(const Token &a) const {
#if(QT_VERSION < 0x050000)
        if(count == a.count)
            return priority > a.priority;
        return count > a.count;
#else
        if(count.load() == a.count.load())
            return priority > a.priority;
        return count.load() > a.count.load();
#endif
    }
};

} //namespace
#endif // GCACHE_H