HomeAbout UsContact Us

C Program to implement custom mutex_lock() and mutex_unlock()

By embeddedSoft
Published in Embedded C/C++
September 07, 2025
1 min read
C Program to implement custom mutex_lock() and mutex_unlock()

Table Of Contents

01
C Program
02
Code Walkthrough

This problem is a tricky question often asked during tech interviews. Here we need to create custom mutex_lock() and mutex_unlock() functions to mimick the actual behavior of mutex APIs. This program implements a mutex using atomic operations and busy waiting (spinning).

C Program

#include <stdio.h>
#include <stdatomic.h>
#include <pthread.h>
typedef struct {
atomic_flag flag;
} Mutex;
void Mutex_Init(Mutex* m) {
atomic_flag_clear(&m->flag); // initially unlocked
}
void Mutex_Lock(Mutex* m) {
while (atomic_flag_test_and_set(&m->flag)) {
// Busy wait (spinning)
}
}
void Mutex_Unlock(Mutex* m) {
atomic_flag_clear(&m->flag);
}
Mutex mylock;
void* worker(void* arg) {
Mutex_Lock(&mylock);
printf("Thread %ld entered critical section\n", (long)arg);
for (volatile int i = 0; i < 100000000; i++); // simulate work
printf("Thread %ld leaving critical section\n", (long)arg);
Mutex_Unlock(&mylock);
return NULL;
}
int main() {
pthread_t t1, t2;
Mutex_Init(&mylock);
pthread_create(&t1, NULL, worker, (void*)1);
pthread_create(&t2, NULL, worker, (void*)2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}

Code Walkthrough

1. The Mutex Structure

typedef struct {
atomic_flag flag;
} Mutex;
  • atomic_flag is a special atomic boolean type.
  • It supports test-and-set operations that are thread-safe.
  • In simple terms: it can check if the lock is taken and set it in one atomic step, so no two threads can acquire it at the same time.

2. Initializing the Mutex

void Mutex_Init(Mutex* m) {
atomic_flag_clear(&m->flag); // initially unlocked
}
  • atomic_flag_clear sets the flag to 0 (unlocked).
  • At the start, the mutex is free, so the first thread can acquire it.

3. Locking the Mutex

void Mutex_Lock(Mutex* m) {
while (atomic_flag_test_and_set(&m->flag)) {
// Busy wait (spinning)
}
}
  • atomic_flag_test_and_set(&m->flag) does two things atomically:
    1. Checks the flag.
    2. Sets it to 1 (locked) if it was 0.
  • If the flag was already 1 → the function returns true → thread cannot enter.
  • The while loop keeps running → this is called busy waiting or spinning.
  • Once the flag becomes 0 (unlocked), the thread acquires the lock and exits the loop.

🔹 Analogy

  • Imagine a single key for a treasure box:
  • If someone has the key → you keep trying to take it repeatedly (spin).
  • When the key is free → you grab it immediately.

4. Unlocking the Mutex

void Mutex_Unlock(Mutex* m) {
atomic_flag_clear(&m->flag);
}
  • Clears the flag → sets it to 0 (unlocked).
  • Now another waiting thread can acquire the mutex.

5. Worker Function (Thread Task)

void* worker(void* arg) {
Mutex_Lock(&mylock);
printf("Thread %ld entered critical section\n", (long)arg);
for (volatile int i = 0; i < 100000000; i++); // simulate work
printf("Thread %ld leaving critical section\n", (long)arg);
Mutex_Unlock(&mylock);
return NULL;
}
  • Each thread locks the mutex before entering the critical section.
  • Only one thread can execute the critical section at a time.
  • After finishing, it unlocks the mutex.

6. Main Function

pthread_t t1, t2;
Mutex_Init(&mylock);
pthread_create(&t1, NULL, worker, (void*)1);
pthread_create(&t2, NULL, worker, (void*)2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
  • Create 2 threads.
  • They both try to enter the critical section.
  • Only one thread can enter at a time because of the mutex.
  • Others spin in the loop until the lock is free.

7. Key Characteristics of This Method

FeatureDescription
TypeSpinlock mutex
Locking behaviorBusy wait (spins until lock is free)
CPU usageHigh if waiting, because thread keeps checking in a loop
Atomic operationatomic_flag_test_and_set ensures thread-safe locking
UnlockingClears the flag, allowing next thread to acquire

🔹 Visual Analogy

Thread 1: acquires lock -> executes critical section
Thread 2: sees lock taken -> keeps spinning (busy wait)
Thread 1: finishes -> unlocks
Thread 2: grabs lock -> executes critical section

Tags

embedded systemsc programmingrtosthreads

Share


Previous Article
C Program to implement modulo (%) operator using bitwise operators
embeddedSoft

embeddedSoft

Insightful articles on embedded systems

Related Posts

C program to implement queue data structure
C program to implement queue data structure
September 08, 2025
1 min
© 2025, All Rights Reserved.
Powered By Netlyft

Quick Links

Advertise with usAbout UsContact Us

Social Media