A fault-tolerant scheduling algorithm based on checkpointing and redundancy for distributed real-time systems