Overview
TheSemaphore class implements a counting semaphore with FIFO queue management and resource assignment tracking. It’s designed for scenarios like managing access to multiple printers, where each thread needs exclusive access to one resource from a pool.
Constructor
The initial count representing the number of available resources. Must be non-negative.Initial State:
count:Math.max(0, initialCount)queue:[]assignments:new Map()
Properties
The number of available resources. Represents how many more threads can enter the protected region.
FIFO queue of blocked threads waiting for a resource to become available.
Maps each thread to its assigned printer/resource index. Used to track which resource belongs to which thread.
Methods
wait(thread, printers)
Attempts to acquire a semaphore token and assign a printer resource to the thread.The thread attempting to acquire a resource.
Array of printer objects, each with an
owner property.- number: Index of the assigned printer (0-based)
- null: No resource available, thread is blocked
- Already assigned: If thread already has a printer (from transfer), returns that printer index
- Resource available (
count > 0): Finds first available printer, decrements count, assigns printer, returns index - No resources: Blocks thread, adds to queue, returns
null
semaphore.js:13
signal(thread, printers)
Releases the thread’s printer resource and transfers it to the next waiting thread if available.The thread releasing its resource. Must have an assigned printer.
Array of printer objects to update ownership.
Object containing:
releasedPrinter(number): Index of the printer that was releasednextThread(Thread | null): The thread that received the printer, ornullif no waiters
- Validation: Throws error if thread has no assigned resource
- Release resource: Removes assignment, clears printer owner
- Has waiters: Directly transfers the same printer to first thread in queue
- No waiters: Increments count (resource returned to pool)
semaphore.js:41
Throws:
Error: “El hilo no tiene recurso asignado para signal” if thread calls signal without a resource
getAssignedPrinter(thread)
Returns the printer index assigned to a thread.The thread to query.
The printer index (0-based) if thread has an assignment, otherwise
null.semaphore.js:70
Usage Example
Direct Transfer Mechanism
When a thread releases a printer, if there are waiting threads, the semaphore directly transfers the same printer resource:- FIFO fairness (first in queue gets resource)
- Immediate resource reuse
- No race conditions
Counting vs Assignment
The semaphore maintains both:- count: Logical number of available slots
- assignments: Physical mapping of threads to specific resources
- Proper blocking/unblocking based on availability
- Resource-specific assignment (which printer a thread is using)
- Clean transfer of exact resources between threads