Line data Source code
1 : /* File caching.
2 : Copyright (C) 2023-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #ifndef GCC_LTO_LTRANS_CACHE_H
21 : #define GCC_LTO_LTRANS_CACHE_H
22 :
23 : #include "lockfile.h"
24 :
25 : using checksum_t = std::array<uint8_t, 32>;
26 :
27 : class ltrans_file_cache
28 : {
29 : public:
30 : /* Cache item representing input/output filename pair. */
31 : struct item
32 : {
33 : item (std::string input, std::string output,
34 : checksum_t input_checksum, uint32_t last_used);
35 : ~item ();
36 :
37 : /* Full path to input filename. */
38 : const std::string input;
39 : /* Full path to output filename. */
40 : const std::string output;
41 : /* Checksum of input file. */
42 : const checksum_t input_checksum;
43 :
44 : /* Larger last_used corresponds to later usage. */
45 : uint32_t last_used;
46 :
47 : /* Lockfile so that output file can be created later than input file. */
48 : lockfile lock;
49 : };
50 :
51 : /* Constructor. Resulting cache item filenames will be
52 : in format `prefix%d[.ltrans]suffix`. */
53 : ltrans_file_cache (const char* dir, const char* prefix, const char* suffix,
54 : size_t soft_cache_size);
55 : /* Destructor. */
56 : ~ltrans_file_cache ();
57 :
58 : /* Loads data about previously cached items from cachedata file.
59 :
60 : Must be called with creation_lock or deletion_lock held to
61 : prevent data race. */
62 : void load_cache ();
63 :
64 : /* Rewrites data about cache items into cachedata file.
65 :
66 : Must be only called when creation_lock or deletion_lock was held since last
67 : call to load_cache. */
68 : void save_cache ();
69 :
70 :
71 : /* Adds input file into cache. Cache item with input file identical to
72 : added input file will be returned as _item.
73 : If the file was already cached, `true` is returned, `false` otherwise.
74 : The added input file is deleted (or moved).
75 :
76 : Must be called with creation_lock held to prevent data race. */
77 : bool add_to_cache (const char* filename, item*& _item);
78 :
79 : /* If exists, returns cache item corresponding to cached input file. */
80 : item* get_item (const char* input);
81 :
82 : /* If no other process holds the deletion_lock, prunes oldest unused cache
83 : items over limit. */
84 : void try_prune ();
85 :
86 : /* Clears cache class, as if only constructor was called. */
87 : void cleanup ();
88 :
89 : /* Cache is enabled if true. */
90 55387 : operator bool ()
91 : {
92 55387 : return dir;
93 : }
94 :
95 : /* Access to already created items can be concurrent with item creation. */
96 : lockfile creation_lock;
97 : /* Access to already created items cannot be concurrent
98 : with item deletion. */
99 : lockfile deletion_lock;
100 :
101 : /* Directory of cache. NULL if cache is disabled. */
102 : const char* dir;
103 : private:
104 : /* Adds given cache item to all relevant datastructures. */
105 : void add_item (item* item);
106 :
107 : /* Creates new cache item with given checksum.
108 : New input/output files are chosen to not collide with other items.
109 :
110 : Must be called with creation_lock held to prevent data race. */
111 : item* create_item (const checksum_t& checksum);
112 :
113 : /* Prunes oldest unused cache items over limit.
114 : Must be called with deletion_lock held to prevent data race. */
115 : void prune ();
116 :
117 : /* Creates cachedata filename for save/load. */
118 : std::string filename_cachedata ();
119 :
120 : /* All cache items in current cache. */
121 : std::vector<item*> items;
122 : std::map<checksum_t, item*> map_checksum;
123 : std::map<std::string, item*> map_input;
124 :
125 : /* Cached filenames are in format "cache_prefix%d[.ltrans]suffix". */
126 : const char* suffix;
127 :
128 : /* If cache items count is larger, prune deletes old items. */
129 : size_t soft_cache_size;
130 :
131 : /* Counter used to populate last_used of items. */
132 : uint32_t usage_counter;
133 :
134 : /* String in format "dir/prefix". */
135 : std::string cache_prefix;
136 : /* Lower indices are occupied. */
137 : uint32_t cache_free_idx;
138 :
139 : /* Buffer for sprintf. */
140 : char* str_buffer;
141 : };
142 :
143 : #endif
|