๐Ÿ”ฅ Preheat

Predict. Preload. Perform.

Adaptive readahead daemon for Linux

View on GitHub

Architecture

This document describes preheatโ€™s internal architecture, including component design, data flow, and system interactions.


System Architecture Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           PREHEAT DAEMON                                โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚   DAEMON    โ”‚  โ”‚   CONFIG    โ”‚  โ”‚   STATE     โ”‚  โ”‚   LOGGING   โ”‚     โ”‚
โ”‚  โ”‚   CORE      โ”‚  โ”‚   PARSER    โ”‚  โ”‚   MANAGER   โ”‚  โ”‚   SYSTEM    โ”‚     โ”‚
โ”‚  โ”‚             โ”‚  โ”‚             โ”‚  โ”‚             โ”‚  โ”‚             โ”‚     โ”‚
โ”‚  โ”‚ Main loop   โ”‚  โ”‚ INI parser  โ”‚  โ”‚ Serialize   โ”‚  โ”‚ File logger โ”‚     โ”‚
โ”‚  โ”‚ Init/term   โ”‚  โ”‚ Validation  โ”‚  โ”‚ Persist     โ”‚  โ”‚ Levels      โ”‚     โ”‚
โ”‚  โ”‚ Signals     โ”‚  โ”‚ Defaults    โ”‚  โ”‚ Load/save   โ”‚  โ”‚ Rotation    โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚         โ”‚                โ”‚                โ”‚                โ”‚            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚  โ”‚                     SHARED DATA STRUCTURES                     โ”‚     โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚     โ”‚
โ”‚  โ”‚  โ”‚  kp_state: Global state containing all application      โ”‚   โ”‚     โ”‚
โ”‚  โ”‚  โ”‚            data, Markov chains, and maps                โ”‚   โ”‚     โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚         โ”‚                                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚                 MONITORING LAYER                    โ”‚                โ”‚
โ”‚  โ”‚                                                     โ”‚                โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚                โ”‚
โ”‚  โ”‚  โ”‚               โ”‚  โ”‚                           โ”‚   โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  /proc reader โ”‚  โ”‚  Track app launches       โ”‚   โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Maps parser  โ”‚  โ”‚  Update statistics        โ”‚   โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Process enum โ”‚  โ”‚  Manage exe entries       โ”‚   โ”‚                โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚  โ”‚  โ”‚  PROC SCANNER โ”‚  โ”‚      SPY MODULE           โ”‚   โ”‚                โ”‚
โ”‚         โ”‚                                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚                 PREDICTION LAYER                    โ”‚                โ”‚
โ”‚  โ”‚                                                     โ”‚                โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚            PROPHET MODULE                   โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚                                             โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Markov chain analysis                      โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Correlation computation                    โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Score calculation                          โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Prediction generation                      โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚         โ”‚                                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚  โ”‚                 READAHEAD LAYER                     โ”‚                โ”‚
โ”‚  โ”‚                                                     โ”‚                โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚          READAHEAD MODULE                   โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚                                             โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Memory budget calculation                  โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  File sorting (block/inode/path)            โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  Parallel readahead workers                 โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ”‚  readahead(2) syscall wrapper               โ”‚    โ”‚                โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚                    โ”‚                    โ”‚
         โ–ผ                    โ–ผ                    โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚ /proc   โ”‚         โ”‚ Config  โ”‚         โ”‚ State File   โ”‚
    โ”‚ (read)  โ”‚         โ”‚ File    โ”‚         โ”‚ (read/write) โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Core Components

Daemon Core (daemon/)

Files: main.c, daemon.c, signals.c

Responsibilities:

Main Loop Pseudocode:

initialize()
load_config()
load_state()

while (running):
    kp_spy_scan()        # Monitor processes
    kp_spy_update_model() # Update Markov chains
    kp_prophet_predict()  # Calculate predictions
    kp_prophet_readahead() # Preload files
    sleep(cycle_time)

save_state()
cleanup()

Configuration (config/)

Files: config.c, config.h, confkeys.h

Data Structure:

struct _kp_conf {
    struct {
        int cycle;           // Scan interval
        gboolean usecorrelation;
        int minsize;
        int memtotal, memfree, memcached;
    } model;
    
    struct {
        gboolean doscan, dopredict;
        int autosave;
        char *mapprefix, *exeprefix;
        int processes;
        int sortstrategy;
    } system;
    
    struct {
        gboolean enable_preheat_scoring;
        double preheat_tool_boost;
    } preheat;
};

State Management (state/)

Files: state.c, state.h

Whatโ€™s Stored:

Serialization Format:

[Header]
PREHEAT_STATE_V1
timestamp

[Executables]
exe_count
for each exe:
    path, size, last_seen, launch_count
    map_count
    for each map:
        path, offset, length

[Markov Chains]
markov_count
for each chain:
    from_app, to_app, transition_count, probability

[Bad Exes]
bad_count
paths of unreadable executables

Monitoring Layer

Process Scanner (monitor/proc.c)

Function: kp_proc_scan()

Enumerates /proc to find running processes:

// Pseudocode
for each /proc/[pid]:
    exe_path = readlink("/proc/[pid]/exe")
    
    if exe_path matches exeprefix:
        maps = parse("/proc/[pid]/maps")
        
        for each map in maps:
            if map.path matches mapprefix:
                add_to_process_list(exe_path, map)

Maps File Format (/proc/[pid]/maps):

address           perms offset   dev   inode      pathname
7f1234560000-... r-xp  00000000 08:01 1234567    /usr/lib/libc.so

Spy Module (monitor/spy.c)

Functions: kp_spy_scan(), kp_spy_update_model()

Tracks application lifecycles:


Prediction Layer

Prophet Module (predict/prophet.c)

Functions: kp_prophet_predict(), kp_prophet_readahead()

Prediction Algorithm:

  1. Get running applications
  2. For each known application:
    • Look up Markov transitions FROM running apps TO this app
    • Calculate transition probability
    • Apply correlation coefficient
    • Compute final score
  3. Sort by score descending
  4. Return top N predictions

Score Calculation:

score = 0.0;

for each running_app:
    p = markov_probability(running_app -> candidate_app)
    if (usecorrelation):
        p *= correlation(running_app, candidate_app)
    score += p

// Normalize
score = log(score + EPSILON)

Markov Chain

Data Structure:

struct _kp_markov {
    char *from_app;      // Source application
    GHashTable *transitions;  // to_app -> count
    int total_count;     // Sum of all transitions
};

// Probability of transition A -> B
P(A->B) = count(A->B) / total_transitions_from(A)

Readahead Layer

Readahead Module (readahead/readahead.c)

Function: kp_readahead_file()

Process:

1. Check memory budget (meminfo)
2. Get predicted apps from prophet
3. Collect all files for predicted apps
4. Sort files by strategy (block/inode/path)
5. For each file:
     fd = open(path, O_RDONLY)
     readahead(fd, 0, file_size)
     close(fd)
6. Track bytes preloaded

Sorting Implementation:

switch (sortstrategy):
    case SORT_NONE:
        // No sorting
    case SORT_PATH:
        qsort(files, by_path)
    case SORT_INODE:
        qsort(files, by_inode)
    case SORT_BLOCK:
        for each file:
            block = get_block_number(fd)
        qsort(files, by_block)

Getting Block Number (for HDD optimization):

// Uses FIBMAP ioctl
ioctl(fd, FIBMAP, &block_number)

Data Flow

Cycle Data Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        ONE CYCLE                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 1: SCAN
/proc โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> Process List
         read /proc/*/exe                 โ”‚
         read /proc/*/maps                โ”‚
                                          โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Running Processes โ”‚
                              โ”‚ + Their Maps      โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
Step 2: LEARN                           โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Compare with      โ”‚
                              โ”‚ Previous State    โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
                     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
                     โ”‚                                      โ”‚
              New processes                          Exited processes
                     โ”‚                                      โ”‚
                     โ–ผ                                      โ–ผ
            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
            โ”‚ Add to Markov   โ”‚                    โ”‚ Record exit     โ”‚
            โ”‚ chain           โ”‚                    โ”‚ transition      โ”‚
            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                     โ”‚                                      โ”‚
                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Updated State     โ”‚
                              โ”‚ (apps + Markov)   โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
Step 3: PREDICT                         โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Prophet: Score    โ”‚
                              โ”‚ all known apps    โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Ranked Prediction โ”‚
                              โ”‚ List              โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
Step 4: PRELOAD                         โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Get files for     โ”‚
                              โ”‚ top predictions   โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚
                                        โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ readahead(2)      โ”‚โ”€โ”€โ”€โ”€โ”€โ”€> Disk Cache
                              โ”‚ each file         โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

File Structure

src/
โ”œโ”€โ”€ daemon/
โ”‚   โ”œโ”€โ”€ main.c          # Entry point, argument parsing
โ”‚   โ”œโ”€โ”€ daemon.c        # Daemonization, main loop
โ”‚   โ””โ”€โ”€ signals.c       # Signal handlers
โ”œโ”€โ”€ config/
โ”‚   โ”œโ”€โ”€ config.c        # Configuration loading
โ”‚   โ”œโ”€โ”€ config.h        # Config structures
โ”‚   โ””โ”€โ”€ confkeys.h      # Key name definitions
โ”œโ”€โ”€ monitor/
โ”‚   โ”œโ”€โ”€ proc.c          # /proc filesystem scanner
โ”‚   โ”œโ”€โ”€ proc.h
โ”‚   โ”œโ”€โ”€ spy.c           # Application tracker
โ”‚   โ””โ”€โ”€ spy.h
โ”œโ”€โ”€ predict/
โ”‚   โ”œโ”€โ”€ prophet.c       # Prediction engine
โ”‚   โ””โ”€โ”€ prophet.h
โ”œโ”€โ”€ readahead/
โ”‚   โ”œโ”€โ”€ readahead.c     # Preloading implementation
โ”‚   โ””โ”€โ”€ readahead.h
โ”œโ”€โ”€ state/
โ”‚   โ”œโ”€โ”€ state.c         # State persistence
โ”‚   โ””โ”€โ”€ state.h
โ””โ”€โ”€ utils/
    โ”œโ”€โ”€ logging.c       # Logging system
    โ””โ”€โ”€ logging.h

External Dependencies

GLib

Preheat uses GLib for:

System Interfaces

Interface Purpose
/proc filesystem Process enumeration, maps
readahead(2) Non-blocking file read
ioctl(FIBMAP) Get file block numbers
open/close File access
signal(2) Signal handling
fork/setsid Daemonization

Memory Layout

Runtime Memory Usage

Daemon Process Memory
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Code Segment (~150 KB)                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Heap:                                   โ”‚
โ”‚   โ”œโ”€โ”€ Application entries (variable)    โ”‚
โ”‚   โ”œโ”€โ”€ Markov chain nodes (variable)     โ”‚
โ”‚   โ”œโ”€โ”€ Map entries (variable)            โ”‚
โ”‚   โ””โ”€โ”€ Working buffers (~100 KB)         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Stack (~1 MB limit)                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Typical total: 5-15 MB depending on tracked apps

Key Data Structures Size

Structure Approximate Size
Application entry ~500 bytes + path strings
Map entry ~200 bytes + path string
Markov node ~100 bytes + transitions
Transition ~20 bytes

Thread Safety

Preheat is single-threaded with one exception:

This design:


Error Handling

Error Recovery Strategy

Error Type Handling
Config parse error Use defaults, log warning
State file missing Start fresh, normal operation
State file corrupt Discard, start fresh
/proc read error Skip process, continue
readahead fail Log, continue with next file
Out of memory Reduce preload budget

Defensive Coding


Previous Up Next
โ† How It Works Documentation Index Configuration โ†’