1/* libs/pixelflinger/codeflinger/CodeCache.h
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18
19#ifndef ANDROID_CODECACHE_H
20#define ANDROID_CODECACHE_H
21
22#include <stdint.h>
23#include <pthread.h>
24#include <sys/types.h>
25
26#include "tinyutils/KeyedVector.h"
27#include "tinyutils/smartpointer.h"
28
29namespace android {
30
31// ----------------------------------------------------------------------------
32
33class AssemblyKeyBase {
34public:
35    virtual ~AssemblyKeyBase() { }
36    virtual int compare_type(const AssemblyKeyBase& key) const = 0;
37};
38
39template  <typename T>
40class AssemblyKey : public AssemblyKeyBase
41{
42public:
43    AssemblyKey(const T& rhs) : mKey(rhs) { }
44    virtual int compare_type(const AssemblyKeyBase& key) const {
45        const T& rhs = static_cast<const AssemblyKey&>(key).mKey;
46        return android::compare_type(mKey, rhs);
47    }
48private:
49    T mKey;
50};
51
52// ----------------------------------------------------------------------------
53
54class Assembly
55{
56public:
57                Assembly(size_t size);
58    virtual     ~Assembly();
59
60    ssize_t     size() const;
61    uint32_t*   base() const;
62    ssize_t     resize(size_t size);
63
64    // protocol for sp<>
65            void    incStrong(const void* id) const;
66            void    decStrong(const void* id) const;
67    typedef void    weakref_type;
68
69private:
70    mutable int32_t     mCount;
71            uint32_t*   mBase;
72            size_t      mSize;
73};
74
75// ----------------------------------------------------------------------------
76
77class CodeCache
78{
79public:
80// pretty simple cache API...
81                CodeCache(size_t size);
82                ~CodeCache();
83
84            sp<Assembly>        lookup(const AssemblyKeyBase& key) const;
85
86            int                 cache(  const AssemblyKeyBase& key,
87                                        const sp<Assembly>& assembly);
88
89private:
90    // nothing to see here...
91    struct cache_entry_t {
92        inline cache_entry_t() { }
93        inline cache_entry_t(const sp<Assembly>& a, int64_t w)
94                : entry(a), when(w) { }
95        sp<Assembly>            entry;
96        mutable int64_t         when;
97    };
98
99    class key_t {
100        friend int compare_type(
101            const key_value_pair_t<key_t, cache_entry_t>&,
102            const key_value_pair_t<key_t, cache_entry_t>&);
103        const AssemblyKeyBase* mKey;
104    public:
105        key_t() { };
106        key_t(const AssemblyKeyBase& k) : mKey(&k)  { }
107    };
108
109    mutable pthread_mutex_t             mLock;
110    mutable int64_t                     mWhen;
111    size_t                              mCacheSize;
112    size_t                              mCacheInUse;
113    KeyedVector<key_t, cache_entry_t>   mCacheData;
114
115    friend int compare_type(
116        const key_value_pair_t<key_t, cache_entry_t>&,
117        const key_value_pair_t<key_t, cache_entry_t>&);
118};
119
120// KeyedVector uses compare_type(), which is more efficient, than
121// just using operator < ()
122inline int compare_type(
123    const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& lhs,
124    const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& rhs)
125{
126    return lhs.key.mKey->compare_type(*(rhs.key.mKey));
127}
128
129// ----------------------------------------------------------------------------
130
131}; // namespace android
132
133#endif //ANDROID_CODECACHE_H
134