Thread Synch AOSV 2020  1.2
LKM for exchanging messages between threads
Macros | Functions
message.h File Reference

Handles all procedures releated to messages of a group device. More...

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/semaphore.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include "types.h"
Include dependency graph for message.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NO_MSG_PRESENT   0
 
#define ALLOC_ERR   -2
 
#define USER_COPY_ERR   -3
 
#define SEM_INIT_ERR   -4 /** @brief Semaphore initialization **/
 
#define MSG_INVALID_FORMAT   -11
 
#define MSG_SIZE_ERROR   -12
 
#define MEMORY_ERROR   -13
 
#define STORAGE_SIZE_ERR   -14
 
#define ALLOC_ERR   -2
 
#define CLASS_EXISTS   -10
 
#define CLASS_ERR   -11
 
#define DEV_CREATION_ERR   -12
 
#define CDEV_ALLOC_ERR   -13
 
#define EMPTY_LIST   -20
 
#define NODE_NOT_FOUND   -21
 
#define INVALID_IOCTL_COMMAND   -1
 
#define CHDEV_ALLOC_ERR   -22
 
#define DEFAULT_GC_RATIO   3
 

Functions

msg_manager_t * createMessageManager (const u_int _max_storage_size, const u_int _max_message_size, garbage_collector_t *garbageCollector)
 Allocate and initialize all the members of a 'msg_manager_t' struct. More...
 
int writeMessage (msg_t *message, msg_manager_t *manager)
 write message on a group queue More...
 
int readMessage (msg_t *dest_buffer, msg_manager_t *manager)
 Read a message from the corresponding queue. More...
 
int copy_msg_from_user (msg_t *kmsg, const char *umsg, const ssize_t _size)
 copy a msg_t structure from user-space to kernel-space More...
 
int copy_msg_to_user (const msg_t *kmsg, __user char *ubuffer, const ssize_t _size)
 copy a msg_t structure from kernel-space to user-space More...
 
void queueGarbageCollector (struct work_struct *work)
 Remove a message from the queue when it was completely delivered. More...
 
bool isDelaySet (const msg_manager_t *manager)
 Check if the message delay is greater than zero on a group. More...
 
void delayedMessageCallback (struct timer_list *timer)
 Called when a timer for a delayed message expires. More...
 
int queueDelayedMessage (msg_t *message, msg_manager_t *manager)
 Insert a delayed message into the pending queue. More...
 
int revokeDelayedMessage (msg_manager_t *manager)
 Remove all the delayed message from the queue. More...
 
int cancelDelay (msg_manager_t *manager)
 Set the delay of messages in the delay queue to zero. More...
 

Detailed Description

Handles all procedures releated to messages of a group device.

Function Documentation

◆ cancelDelay()

int cancelDelay ( msg_manager_t *  manager)

Set the delay of messages in the delay queue to zero.

Parameters
[in]managerThe group's message manager
Returns
The number of messages which delay was cancelled
Note
At the moment the function locks the delayed queue, set all timers to zero and unlock the queue. This means that while the function loops through the queue, timer's callback will wait since the queue is locked.

◆ copy_msg_from_user()

int copy_msg_from_user ( msg_t *  kmsg,
const char *  umsg,
const ssize_t  _size 
)

copy a msg_t structure from user-space to kernel-space

Parameters
[out]kmsgKernel-space msg_t
[in]umsgUser-space msg_t
Return values
0on success
-EFAULTif the copy fails
Todo:
Check thread-safety of the function
Note
The kmsg structure must be allocated

◆ copy_msg_to_user()

int copy_msg_to_user ( const msg_t *  kmsg,
__user char *  ubuffer,
const ssize_t  _size 
)

copy a msg_t structure from kernel-space to user-space

Parameters
[in]kmsgKernel-space msg_t
[out]umsgUser-space buffer
Return values
0on success
-EFAULTif the copy fails
Todo:
Check thread-safety of the function
Note
The umsg structure must be allocated

◆ createMessageManager()

msg_manager_t* createMessageManager ( const u_int  _max_storage_size,
const u_int  _max_message_size,
garbage_collector_t *  garbage_collector 
)

Allocate and initialize all the members of a 'msg_manager_t' struct.

Parameters
[in]_max_message_sizeConfigurable param
[in]_max_storage_sizeConfigurable param
[in]garbageCollectorFunctionPointer to the work_struct responsible for garbage collection
Return values
An'msg_manager_t' pointer to an allocated an initialized 'msg_manager_t' struct
ANULL pointer in case the 'kmalloc' fails

◆ delayedMessageCallback()

void delayedMessageCallback ( struct timer_list *  timer)

Called when a timer for a delayed message expires.

The function simply take the existing 't_message_delayed_deliver' structure, extract the 'msg_t' field and write it into the FIFO queue via the 'writeMessage' function.

Parameters
[in]timerThe timer that elasped
Returns
nothing

◆ isDelaySet()

bool isDelaySet ( const msg_manager_t *  manager)

Check if the message delay is greater than zero on a group.

Parameters
[in]managerA pointer to the message manager of the group
Note
This function is thread-safe
Return values
trueIf the delay is greater than zero
falseIf the delay is zero

◆ queueDelayedMessage()

int queueDelayedMessage ( msg_t *  message,
msg_manager_t *  manager 
)

Insert a delayed message into the pending queue.

Parameters
[in]messageThe message to insert into the queue
[in]managerA pointer to the current msg_manager_t of the group
Return values
0on success
-1on error

◆ queueGarbageCollector()

void queueGarbageCollector ( struct work_struct *  work)

Remove a message from the queue when it was completely delivered.

Parameters
[in]workThe work struct contained inside "msg_manager_t"
Returns
nothing
Todo:
Check if size calculation are done correctly
Note
This function has three critical section, therefore it could be a bottleneck of the module

◆ readMessage()

int readMessage ( msg_t *  dest_buffer,
msg_manager_t *  manager 
)

Read a message from the corresponding queue.

Return values
0on success
1if no message is present
-1on critical error

This should't be necessary since the message's sender is automatically added in the list of recipients and, consequently, the 'wasDelivered' function should skip it. However for unknown reason this does not always happens (especially if the message is delayed)

Bug:
: when 'revoke delay' functionality is called, messages trigger this if and will not be delivered

◆ revokeDelayedMessage()

int revokeDelayedMessage ( msg_manager_t *  manager)

Remove all the delayed message from the queue.

Parameters
[in]managerThe message manager of the group
Note
This function is thread safe with respect to the list of delayed message
Returns
The number of delayed messages which revoked

◆ writeMessage()

int writeMessage ( msg_t *  message,
msg_manager_t *  manager 
)

write message on a group queue

Parameters
[in]messageThe data pointed must never be deallocatated
[in]managerPointer to the message manager
[in]recipientsThe head of the linked list containing the thread recipients
Return values
0on success
STORAGE_SIZE_ERRif the message does not respect the group's size limits
ALLOC_ERRif some allocation fails
Note
Must be protected by a write-spinlock to avoid concurrent modification of The recipient data-structure and manager's message queue