summaryrefslogtreecommitdiff
path: root/lcmodule/source/cnh1605551_ldr_utilities/critical_section/critical_section.c
blob: b6dafd3daac3a82b052315ab00c95bc54896b767 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*******************************************************************************
 * $Copyright ST-Ericsson 2011 $
 ******************************************************************************/

/*
 * @addtogroup critical_section
 * @{
 */

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include "stdlib.h"
#include "t_basicdefinitions.h"
#include "r_critical_section.h"
#include "r_atomic_functions.h"

/*******************************************************************************
 * File scope types, constants and variables
 ******************************************************************************/
#define CS_LOCKED   1
#define CS_UNLOCKED 0
/*******************************************************************************
 * Declaration of internal functions
 ******************************************************************************/

/*******************************************************************************
 * Definition of external functions
 ******************************************************************************/
/**
 * Perform initialization of Critical Section.
 *
 * Creates a critical section object and returns pointer to it for later usage
 * when it is needed to enter and leave the critical part of the code,
 * and destroy the critical section object when not used anymore.
 *
 * @retval  Pointer to initialized critical section object if initialization was
 *          successful, otherwise NULL.
 */
CriticalSection_t Do_CriticalSection_Create(void)
{
    uint32 *cs = (uint32 *)malloc(sizeof(uint32));

    if (NULL != cs) {
        *cs = CS_UNLOCKED;
    }

    return cs;
}

/**
 * Free resources used for Critical Section object.
 *
 * Free all resources and destroy the critical section object given as parameter
 * to the function.
 *
 * @param [in] CriticalSectionObject  Pointer to pointer at the object to be destroyed.
 *
 * @retval  None.
 */
void Do_CriticalSection_Destroy(CriticalSection_t *CriticalSectionObject)
{
    uint32 **cs = (uint32 **)CriticalSectionObject;

    if (NULL != *cs) {
        free(*cs);
        *cs = NULL;
    }
}

/**
 * Enter to the Critical Section code.
 *
 * Take ownership over critical section object and execute the part of the code
 * covered by the Critical Section object passed as parameter to the function.
 *
 * @param [in] CriticalSectionObject  Pointer to the object used to exclusively
 *                                    lock some critical part of the code.
 *
 * @retval  TRUE if Critical Section code entered successfully, otherwise FALSE.
 */
boolean Do_CriticalSection_Enter(CriticalSection_t CriticalSectionObject)
{
    volatile uint32 *cs = (volatile uint32 *)CriticalSectionObject;

    if (NULL != cs) {
        uint32 cs_status = CS_LOCKED;
        cs_status = Do_Atomic_CompareAndSwap(cs, CS_UNLOCKED, CS_LOCKED);

        if (CS_UNLOCKED == cs_status) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    return TRUE;
}

/**
 * Leave the Critical Section code.
 *
 * Release the Critical Section object when finished execution to allow someone
 * else to execute the code covered by the Critical Section object passed as
 * parameter to the function.
 *
 * @param [in] CriticalSectionObject  Pointer to the object used to exclusively
 *                                    lock some critical part of the code.
 *
 * @retval  None.
 */
void Do_CriticalSection_Leave(CriticalSection_t CriticalSectionObject)
{
    volatile uint32 *cs = (volatile uint32 *)CriticalSectionObject;

    if (NULL != cs) {
        uint32 cs_status = CS_UNLOCKED;
        cs_status = Do_Atomic_CompareAndSwap(cs, CS_LOCKED, CS_UNLOCKED);

        if (CS_LOCKED == cs_status) {
            /* SUCCESS */
        } else {
            /* FAILED */
        }
    }
}

/*******************************************************************************
 * Definition of internal functions
 ******************************************************************************/

/* @} */