aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-ltrans-cache.h
blob: 6b31276be7422f3aea66d9c3840eb7bda6cb4b73 (plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* File caching.
   Copyright (C) 2023-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_LTO_LTRANS_CACHE_H
#define GCC_LTO_LTRANS_CACHE_H

#include "lockfile.h"

using checksum_t = std::array<uint8_t, 32>;

class ltrans_file_cache
{
public:
  /* Cache item representing input/output filename pair.  */
  struct item
  {
    item (std::string input, std::string output,
	  checksum_t input_checksum, uint32_t last_used);
    ~item ();

    /* Full path to input filename.  */
    const std::string input;
    /* Full path to output filename.  */
    const std::string output;
    /* Checksum of input file.  */
    const checksum_t input_checksum;

    /* Larger last_used corresponds to later usage.  */
    uint32_t last_used;

    /* Lockfile so that output file can be created later than input file.  */
    lockfile lock;
  };

  /* Constructor.  Resulting cache item filenames will be
     in format `prefix%d[.ltrans]suffix`.  */
  ltrans_file_cache (const char* dir, const char* prefix, const char* suffix,
		     size_t soft_cache_size);
  /* Destructor.  */
  ~ltrans_file_cache ();

  /* Loads data about previously cached items from cachedata file.

     Must be called with creation_lock or deletion_lock held to
     prevent data race.  */
  void load_cache ();

  /* Rewrites data about cache items into cachedata file.

     Must be only called when creation_lock or deletion_lock was held since last
     call to load_cache.  */
  void save_cache ();


  /* Adds input file into cache.  Cache item with input file identical to
     added input file will be returned as _item.
     If the file was already cached, `true` is returned, `false` otherwise.
     The added input file is deleted (or moved).

     Must be called with creation_lock held to prevent data race.  */
  bool add_to_cache (const char* filename, item*& _item);

  /* If exists, returns cache item corresponding to cached input file.  */
  item* get_item (const char* input);

  /* If no other process holds the deletion_lock, prunes oldest unused cache
     items over limit.  */
  void try_prune ();

  /* Clears cache class, as if only constructor was called.  */
  void cleanup ();

  /* Cache is enabled if true.  */
  operator bool ()
  {
    return dir;
  }

  /* Access to already created items can be concurrent with item creation.  */
  lockfile creation_lock;
  /* Access to already created items cannot be concurrent
     with item deletion.  */
  lockfile deletion_lock;

  /* Directory of cache.  NULL if cache is disabled.  */
  const char* dir;
private:
  /* Adds given cache item to all relevant datastructures.  */
  void add_item (item* item);

  /* Creates new cache item with given checksum.
     New input/output files are chosen to not collide with other items.

     Must be called with creation_lock held to prevent data race.  */
  item* create_item (checksum_t checksum);

  /* Prunes oldest unused cache items over limit.
     Must be called with deletion_lock held to prevent data race.  */
  void prune ();

  /* Creates cachedata filename for save/load.  */
  std::string filename_cachedata ();

  /* All cache items in current cache.  */
  std::vector<item*> items;
  std::map<checksum_t, item*> map_checksum;
  std::map<std::string, item*> map_input;

  /* Cached filenames are in format "prefix%d[.ltrans]suffix".  */
  const char* prefix;
  const char* suffix;

  /* If cache items count is larger, prune deletes old items.  */
  size_t soft_cache_size;

  /* Counter used to populate last_used of items.  */
  uint32_t usage_counter;

  /* String in format "dir/prefix".  */
  std::string cache_prefix;
  /* Lower indices are occupied.  */
  uint32_t cache_free_idx;

  /* Buffer for sprintf.  */
  char* str_buffer;
};

#endif