/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/lock.h

  • Committer: Suren A. Chilingaryan
  • Date: 2015-09-24 02:28:45 UTC
  • mfrom: (305.1.19 views)
  • Revision ID: csa@suren.me-20150924022845-p7hc8lh8v0q48g0r
Finalyze XML support and provide initial support for views (only descriptions so far)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
 * @file lock.h
3
 
 * @skip author zilio nicolas, nicolas.zilio@hotmail.fr
4
3
 * @brief this file is the header file for the functions that implement a semaphore API for the pcitool program, using pthread robust mutexes.
5
 
 * @details the use of pthread robust mutexes  was chosen due to the fact we privilege security over fastness, and that pthread mutexes permits to recover semaphores even with crash ,and that it does not require access to resources that can be easily accessible from extern usage as flock file locking mechanism. A possible other locking mechanism could be the sysv semaphores, but we have a problem of how determine a perfect hash for the init function, and more, benchmarks proves that sysv semaphore aren't that stable and that with more than 10 locks/unlocks, pthread is better in performance, so that should suits more to the final pcitool program. 
 
4
 * @details the use of pthread robust mutexes  was chosen due to the fact we privilege security over fastness, and that pthread mutexes permits to recover semaphores even with crash ,and that it does not require access to resources that can be easily accessible from extern usage as flock file locking mechanism. A possible other locking mechanism could be the sysv semaphores, but we have a problem of how determine a perfect hash for the init function, and more, benchmarks proves that sysv semaphore aren't that stable. For pure locking/unlocking, pthread is better in performance than sysV, but it suffers from big initialization times. In this sense, a kernel memory space is used for saving the locks, and persistence permits to avoid initializations over uses.
 
5
 *
6
6
 * We considered that mutex implmentation is enough compared to a reader/writer implementation. If it should change, please go to sysv semaphore.
 
7
 *
7
8
 * Basic explanation on how semaphores here work: a semaphore here is a positive integer, thus that can't go below zero, which is initiated with a value. when a process want access to the critical resource, it asks to decrement the value of the semaphore, and when it has finished, it reincrements it.basically, when the semaphore is equal to zero, any process must have to wait for it to be reincremented before decrementing it again. Here are defined two types of access to the semaphore corresponding to the reader/writer problem : an exclusive lock, which means that no other process than the one who have the resource can access it; a shared lock, which means that other processes who want to access to the resource with a shared lock can have the access, but a concurrent process who want to access the semaphore with an exclusive lock won't be able to.
8
 
 * explanation on locks here : here locks are registered in kernel memory, where they are defined by a pthread_mutex_t and a name, which corresponds to a register or processus. The iterations like searching a lock are done on names.
 
9
 * explanation on locks here : here locks are registered in kernel memory, where they are defined by a pthread_mutex_t and an identifier name, which corresponds most of the time to a mix of the register associated name and processus (but it's up to the user). The iterations like searching a lock are done on this id name.
9
10
 */
10
11
 
11
12
#ifndef _PCILIB_LOCK_H
12
13
#define _PCILIB_LOCK_H
13
14
 
14
 
#define PCILIB_LOCK_SIZE 128            /**< size of one lock, determine so the size of the protocol_name in the way locks are registered. 40 bytes are necessary for the mutex structure, so we have a protocol name of length LOCK_SIZE-40*/
 
15
#define PCILIB_LOCK_SIZE 128            /**< size of one lock. indeed, as we can't allocate easily on the fly memory in the kernel, fixed size have been chosen. determines so the size of the identifier name in the way locks are registered. 40 bytes are necessary for the mutex structure, so we have an id name of length LOCK_SIZE-40*/
15
16
 
16
17
#include <pcilib.h>
17
18
 
18
19
/**
19
 
 * type that defines possible flags when locking a lock by calling pcilib_lock
 
20
 * type that defines possible flags for a lock, defining how a lock should be handled by the locking functions
20
21
 */
21
22
typedef enum {
22
23
    PCILIB_LOCK_FLAGS_DEFAULT = 0,      /**< Default flags */
23
 
    PCILIB_LOCK_FLAG_UNLOCKED = 1,      /**< Perform operation unlocked (protected by global flock during initialization of locking subsystem) */
 
24
    PCILIB_LOCK_FLAG_UNLOCKED = 1,      /**< Perform operations unlocked, thus without taking care of the lock (protected by global flock during initialization of locking subsystem) */
24
25
    PCILIB_LOCK_FLAG_PERSISTENT = 2     /**< Do not create robust mutexes, but preserve the lock across application launches */
25
26
} pcilib_lock_flags_t;
26
27
 
 
28
/** structure defining a lock*/
27
29
typedef struct pcilib_lock_s pcilib_lock_t;
28
30
 
29
31
 
32
34
#endif
33
35
 
34
36
/**
35
 
 * this function initialize a new semaphore in the kernel given a name that corresponds to a specific processus if the semaphore is not already initialized given the name that permits to differentiate semaphores, and then return the integer that points to the semaphore that have been initialized or to a previously already initialized semaphore.
36
 
 * @param[in] lock - pointer to lock to initialize
37
 
 * @param[in] flags - flags
 
37
 *this function initializes a lock, by setting correctly its property given the flags associated.
 
38
 * @param[in,out] lock - pointer to lock to initialize
 
39
 * @param[in] flags - flags: if it's set to two, then not a robust mutex is created
38
40
 * @param[in] lock_id - lock identificator
39
41
 * @return error code or 0 on success
40
42
 */
41
43
int pcilib_init_lock(pcilib_lock_t *lock, pcilib_lock_flags_t flags, const char *lock_id);
42
44
 
43
45
/**
44
 
 * this function uninitialize a lock in kernel memory and set the corresponding name to 0
45
 
 * @param[in] lock_ctx the pointer that points to the lock.
 
46
 * this function will unref the defined lock. Any subsequent tries to lock it without reinitializaing it will fail.
 
47
 * @param[in,out] lock_ctx - the pointer that points to the lock.
46
48
 */
47
49
void pcilib_free_lock(pcilib_lock_t *lock_ctx);
48
50
 
49
 
 
 
51
/**
 
52
 * this function gives the identifier name associated to a lock in the kernel space
 
53
 * @param[in] loc - pointer to the lock we want the name
 
54
 * @return string corresponding to the name
 
55
 */
50
56
const char *pcilib_lock_get_name(pcilib_lock_t *lock);
51
57
 
52
58
 
53
59
/**
54
 
 * Increment reference count. Not thread/process safe unless system supports stdatomic (gcc 4.9+).
55
 
 * In this case, the access should be synchronized by the caller
56
 
 * @param[in] lock - pointer to initialized lock
 
60
 * Increment reference count(number of processes that may access the given lock).
 
61
 * Not thread/process safe unless system supports stdatomic (gcc 4.9+). In this case, the access should be synchronized by the caller.
 
62
 * @param[in,out] lock - pointer to initialized lock
57
63
 */
58
64
void pcilib_lock_ref(pcilib_lock_t *lock);
59
65
 
60
66
/**
61
 
 * Decrement reference count. Not thread/process safe unless system supports stdatomic (gcc 4.9+).
62
 
 * In this case, the access should be synchronized by the caller
63
 
 * @param[in] lock - pointer to initialized lock
 
67
 * Decrement reference count(number of processes that may access the given lock).
 
68
 * Not thread/process safe unless system supports stdatomic (gcc 4.9+). In this case, the access should be synchronized by the caller
 
69
 * @param[in,out] lock - pointer to initialized lock
64
70
 */
65
71
void pcilib_lock_unref(pcilib_lock_t *lock);
66
72
 
67
73
/**
68
 
 * Return _approximate_ number of lock references. The crashed applications will may not unref.
69
 
 * @param[in] lock - pointer to initialized lock
 
74
 * Return _approximate_ number of lock references as the crashed applications will may not unref.
 
75
 * @param[in,out] lock - pointer to initialized lock
 
76
 * @return the number of lock refs
70
77
 */
71
78
size_t pcilib_lock_get_refs(pcilib_lock_t *lock);
72
79
 
 
80
/**
 
81
 * gets the flags associated to the given lock
 
82
 * @param[in] lock - the lock we want to know the flags
 
83
 * @return value of the flag associated
 
84
 */
73
85
pcilib_lock_flags_t pcilib_lock_get_flags(pcilib_lock_t *lock);
74
86
 
75
87
/**
76
 
 * this function will take a lock for the mutex pointed by lock
77
 
 * @param[in] lock the pointer to the mutex
78
 
 * @param[in] flags define the type of lock wanted 
79
 
 * @param[in] timeout defines timeout 
 
88
 * this function will call different locking functions to acquire the given lock. Given the flags, it is thus possible to: 
 
89
 *      1) the process requesting the lock will be held till it can acquire it
 
90
 *      2)the lock is tried to be acquired, if the lock can be acquired then it is, if not, then the function returns immediatly and the lock is not taken at all
 
91
 *      3) same than previous, but it's possible to define a waiting time to acquire the lock before returning
 
92
 *
 
93
 * @param[in] lock - the pointer to the mutex
 
94
 * @param[in] flags - define the type of lock wanted 
 
95
 * @param[in] timeout - the waiting time if asked, before the function returns without having obtained the lock, in micro seconds
 
96
 * @return error code or 0 for correctness
80
97
 */
81
98
int pcilib_lock_custom(pcilib_lock_t* lock, pcilib_lock_flags_t flags, pcilib_timeout_t timeout);
82
99
 
83
100
/**
84
 
 * this function will take a lock for the mutex pointed by lock
85
 
 * @param[in] lock the pointer to the mutex
 
101
 * function to acquire a lock, and wait till the lock can be acquire
 
102
 * @param[in] lock - the pointer to the mutex
 
103
 * @return error code or 0 for correctness
86
104
 */
87
105
int pcilib_lock(pcilib_lock_t* lock);
88
106
 
89
107
/**
90
 
 * this function will try to take a lock for the mutex pointed by lock
91
 
 * @param[in] lock the pointer to the mutex
 
108
 * this function will try to take a lock for the mutex pointed by lockfunction to acquire a lock, but that returns immediatly if the lock can't be acquired on first try
 
109
 * @param[in] lock - the pointer to the mutex
 
110
 * @return error code or 0 for correctness
92
111
 */
93
112
int pcilib_try_lock(pcilib_lock_t* lock);
94
113
 
95
114
 
96
115
/**
97
 
  * this function will unlock the lock pointed by lock 
98
 
 * @param[in] lock the integer that points to the semaphore
 
116
  * this function unlocks the lock pointed by lock 
 
117
 * @param[in] lock - the integer that points to the semaphore
99
118
 */
100
119
void pcilib_unlock(pcilib_lock_t* lock);
101
120