-
Notifications
You must be signed in to change notification settings - Fork 303
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Wait-Die Deadlock Avoidance Algorithm
- Loading branch information
Showing
2 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
Deadlock avoidance algorithm/Wait and Die Algorithm/program.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <time.h> | ||
#include <stdbool.h> | ||
|
||
#define MAX_TRANSACTIONS 5 // Maximum number of transactions | ||
#define MAX_RESOURCES 3 // Maximum number of resources | ||
|
||
typedef struct { | ||
int id; // Transaction ID | ||
int timestamp; // Transaction's timestamp (used for age comparison) | ||
} Transaction; | ||
|
||
typedef struct { | ||
bool is_locked; // Resource lock status | ||
Transaction *locked_by; // Pointer to the transaction that holds the lock | ||
} Resource; | ||
|
||
Transaction transactions[MAX_TRANSACTIONS]; | ||
Resource resources[MAX_RESOURCES]; | ||
|
||
// Initialize transactions with unique IDs and timestamps | ||
void initialize_transactions() { | ||
srand(time(NULL)); | ||
for (int i = 0; i < MAX_TRANSACTIONS; i++) { | ||
transactions[i].id = i + 1; | ||
transactions[i].timestamp = rand() % 100; // Random timestamp for demonstration | ||
} | ||
} | ||
|
||
// Initialize resources as unlocked | ||
void initialize_resources() { | ||
for (int i = 0; i < MAX_RESOURCES; i++) { | ||
resources[i].is_locked = false; | ||
resources[i].locked_by = NULL; | ||
} | ||
} | ||
|
||
// Function to simulate requesting a resource | ||
void request_resource(int trans_id, int res_id) { | ||
Transaction *transaction = &transactions[trans_id]; | ||
Resource *resource = &resources[res_id]; | ||
|
||
printf("Transaction %d (Timestamp %d) requesting Resource %d\n", | ||
transaction->id, transaction->timestamp, res_id); | ||
|
||
// If resource is not locked, grant it to the transaction | ||
if (!resource->is_locked) { | ||
resource->is_locked = true; | ||
resource->locked_by = transaction; | ||
printf("Resource %d granted to Transaction %d\n", res_id, transaction->id); | ||
} else { | ||
// If resource is locked, apply Wait-Die scheme | ||
Transaction *current_holder = resource->locked_by; | ||
|
||
if (transaction->timestamp < current_holder->timestamp) { | ||
// If transaction is older, it waits | ||
printf("Transaction %d waits for Resource %d held by Transaction %d\n", | ||
transaction->id, res_id, current_holder->id); | ||
} else { | ||
// If transaction is younger, it dies (abort) | ||
printf("Transaction %d aborted (dies) as it is younger than Transaction %d holding Resource %d\n", | ||
transaction->id, current_holder->id, res_id); | ||
} | ||
} | ||
} | ||
|
||
// Function to simulate transactions requesting resources | ||
void simulate_requests() { | ||
request_resource(0, 1); // Transaction 1 requests Resource 2 | ||
request_resource(1, 1); // Transaction 2 requests Resource 2 (Wait or Die based on timestamps) | ||
request_resource(2, 0); // Transaction 3 requests Resource 1 | ||
request_resource(3, 1); // Transaction 4 requests Resource 2 (Wait or Die based on timestamps) | ||
} | ||
|
||
int main() { | ||
initialize_transactions(); | ||
initialize_resources(); | ||
|
||
printf("Simulating Wait-Die Deadlock Avoidance...\n"); | ||
simulate_requests(); | ||
|
||
return 0; | ||
} |
57 changes: 57 additions & 0 deletions
57
Deadlock avoidance algorithm/Wait and Die Algorithm/readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Wait-Die Deadlock Avoidance Algorithm in C | ||
|
||
This project implements the **Wait-Die Algorithm** in C, a deadlock avoidance technique used primarily in database and transaction management systems. The Wait-Die scheme ensures that deadlocks do not occur by enforcing a priority rule based on transaction age (timestamp), allowing only specific requests while aborting others. | ||
|
||
## Table of Contents | ||
- [Introduction](#introduction) | ||
- [Algorithm Overview](#algorithm-overview) | ||
- [Features](#features) | ||
- [Example](#example) | ||
- [Limitations](#limitations) | ||
|
||
## Introduction | ||
|
||
The Wait-Die Algorithm is a deadlock avoidance algorithm that manages resource allocation based on transaction age. When a transaction requests a resource that is already held by another transaction, the algorithm uses timestamps to determine whether the requesting transaction should wait or be aborted ("die"). This approach prevents deadlocks by avoiding circular waiting conditions. | ||
|
||
## Algorithm Overview | ||
|
||
The Wait-Die Algorithm works as follows: | ||
- **Age Comparison**: Each transaction is assigned a timestamp when it begins, representing its age. | ||
- **Wait Rule**: If a younger transaction requests a resource held by an older transaction, it waits. | ||
- **Die Rule**: If an older transaction requests a resource held by a younger transaction, the older transaction is aborted (dies) and can retry later. | ||
|
||
This scheme avoids deadlock by preventing a cycle in the wait-for graph, thus maintaining system safety. | ||
|
||
## Features | ||
|
||
- **Deadlock Avoidance**: Prevents deadlock by enforcing a strict priority rule based on transaction age. | ||
- **Simple Priority System**: Uses timestamps to decide which transactions wait and which are aborted. | ||
- **Efficient for Database Systems**: Commonly used in databases and transactional systems to manage locks on resources. | ||
|
||
## Example | ||
|
||
### Sample Scenario | ||
|
||
Assume we have three transactions with timestamps and two resources: | ||
|
||
| Transaction | ID | Timestamp | | ||
|-------------|----|-----------| | ||
| T1 | 1 | 10 | | ||
| T2 | 2 | 15 | | ||
| T3 | 3 | 5 | | ||
|
||
#### Simulation | ||
|
||
1. **Transaction T1 requests Resource R1**: Granted. | ||
2. **Transaction T2 requests Resource R1**: Transaction T2 is younger than T1, so it waits. | ||
3. **Transaction T3 requests Resource R1**: Transaction T3 is older than T1, so T1 is aborted (dies) and releases R1 for T3. | ||
|
||
This approach ensures the system remains deadlock-free by allowing older transactions to preempt younger ones if necessary. | ||
|
||
## Limitations | ||
|
||
- **Transaction-Based**: Suited for transactional systems; not typically used for general-purpose resource allocation. | ||
- **Fixed Priority**: Transaction age remains fixed, so newer transactions may experience more aborts. | ||
- **Non-Preemptive Resources**: The algorithm assumes resources are non-preemptive, meaning a held resource cannot be forcibly taken from a transaction. | ||
|
||
This implementation demonstrates a simplified version of the Wait-Die algorithm for educational purposes. For a real-world application, further refinements would be required to handle complex resource and transaction management scenarios. |