File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <acpi/acpica/acpi.h>
0029 #include <rtems.h>
0030
0031 #include <errno.h>
0032 #include <pthread.h>
0033
0034 static void ms_timeout_to_abs_timespec(uint32_t timeout, struct timespec *abstime)
0035 {
0036 clock_gettime(CLOCK_REALTIME, abstime);
0037 abstime->tv_sec += timeout / 1000;
0038 abstime->tv_nsec += (timeout % 1000) * 1000000;
0039 }
0040
0041 typedef struct {
0042 pthread_mutex_t mutex;
0043 pthread_cond_t wait_cond;
0044 pthread_cond_t delete_cond;
0045 uint32_t units;
0046 uint32_t max_units;
0047 uint32_t waiters;
0048 bool is_pending_delete;
0049 } acpi_semaphore;
0050
0051 ACPI_STATUS AcpiOsCreateSemaphore(
0052 UINT32 MaxUnits,
0053 UINT32 InitialUnits,
0054 ACPI_SEMAPHORE* OutHandle
0055 )
0056 {
0057 acpi_semaphore* ac_sem;
0058
0059 if (OutHandle == NULL || MaxUnits == 0 || InitialUnits > MaxUnits)
0060 return (AE_BAD_PARAMETER);
0061
0062 ac_sem = malloc(sizeof(acpi_semaphore));
0063 if (ac_sem == NULL) {
0064 return (AE_NO_MEMORY);
0065 }
0066
0067 if (pthread_mutex_init(&ac_sem->mutex, NULL) != 0 ||
0068 pthread_cond_init(&ac_sem->wait_cond, NULL) != 0 ||
0069 pthread_cond_init(&ac_sem->delete_cond, NULL) != 0)
0070 {
0071 free(ac_sem);
0072 return (AE_ERROR);
0073 }
0074 ac_sem->units = InitialUnits;
0075 ac_sem->max_units = MaxUnits;
0076 ac_sem->waiters = 0;
0077 ac_sem->is_pending_delete = false;
0078
0079
0080 *OutHandle = (ACPI_SEMAPHORE) ac_sem;
0081
0082 return (AE_OK);
0083 }
0084
0085 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
0086 {
0087 int eno;
0088 acpi_semaphore* ac_sem = (acpi_semaphore*) Handle;
0089
0090 if (ac_sem == NULL) {
0091 return (AE_BAD_PARAMETER);
0092 }
0093
0094 eno = pthread_mutex_lock(&ac_sem->mutex);
0095 if (eno != 0) {
0096 return (AE_ERROR);
0097 }
0098
0099
0100 ac_sem->is_pending_delete = true;
0101 pthread_cond_broadcast(&ac_sem->wait_cond);
0102 while (ac_sem->waiters > 0) {
0103 pthread_cond_wait(&ac_sem->delete_cond, &ac_sem->mutex);
0104 }
0105
0106 pthread_mutex_unlock(&ac_sem->mutex);
0107
0108 pthread_mutex_destroy(&ac_sem->mutex);
0109 pthread_cond_destroy(&ac_sem->wait_cond);
0110 pthread_cond_destroy(&ac_sem->delete_cond);
0111
0112 free(ac_sem);
0113
0114 return (AE_OK);
0115 }
0116
0117 ACPI_STATUS AcpiOsWaitSemaphore(
0118 ACPI_SEMAPHORE Handle,
0119 UINT32 Units,
0120 UINT16 Timeout
0121 )
0122 {
0123 int eno;
0124 ACPI_STATUS ac_status = (AE_OK);
0125 acpi_semaphore* ac_sem = (acpi_semaphore*) Handle;
0126
0127 if (ac_sem == NULL || Units == 0) {
0128 return (AE_BAD_PARAMETER);
0129 }
0130
0131 eno = pthread_mutex_lock(&ac_sem->mutex);
0132 if (eno != 0) {
0133 return (AE_ERROR);
0134 }
0135
0136 if (ac_sem->max_units != ACPI_NO_UNIT_LIMIT && ac_sem->max_units < Units) {
0137 return (AE_LIMIT);
0138 }
0139
0140 switch (Timeout) {
0141 case ACPI_DO_NOT_WAIT:
0142 if (ac_sem->units < Units) {
0143 ac_status = (AE_TIME);
0144 }
0145
0146 break;
0147 case ACPI_WAIT_FOREVER:
0148 ac_sem->waiters++;
0149 while (ac_sem->units < Units) {
0150 pthread_cond_wait(&ac_sem->wait_cond, &ac_sem->mutex);
0151
0152 if (ac_sem->is_pending_delete) {
0153 ac_status = (AE_ERROR);
0154 pthread_cond_signal(&ac_sem->delete_cond);
0155 break;
0156 }
0157 }
0158 ac_sem->waiters--;
0159
0160 break;
0161 default:
0162 struct timespec abstime;
0163 ms_timeout_to_abs_timespec(Timeout, &abstime);
0164
0165 ac_sem->waiters++;
0166 while (ac_sem->units < Units) {
0167 eno = pthread_cond_timedwait(&ac_sem->wait_cond, &ac_sem->mutex, &abstime);
0168
0169 if (ac_sem->is_pending_delete) {
0170 ac_status = (AE_ERROR);
0171 pthread_cond_signal(&ac_sem->delete_cond);
0172 break;
0173 }
0174
0175 if (eno == ETIMEDOUT) {
0176 ac_status = (AE_TIME);
0177 break;
0178 }
0179 }
0180 ac_sem->waiters--;
0181
0182 break;
0183 }
0184
0185 if (ac_status == (AE_OK)) {
0186 ac_sem->units -= Units;
0187 }
0188
0189 pthread_mutex_unlock(&ac_sem->mutex);
0190
0191 return ac_status;
0192 }
0193
0194 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
0195 {
0196 int eno;
0197 acpi_semaphore* ac_sem = (acpi_semaphore*) Handle;
0198
0199 if (ac_sem == NULL || Units == 0) {
0200 return (AE_BAD_PARAMETER);
0201 }
0202
0203 eno = pthread_mutex_lock(&ac_sem->mutex);
0204 if (eno != 0) {
0205 return (AE_ERROR);
0206 }
0207
0208 if (ac_sem->max_units != ACPI_NO_UNIT_LIMIT &&
0209 ac_sem->units + Units > ac_sem->max_units)
0210 {
0211 return (AE_LIMIT);
0212 }
0213
0214 ac_sem->units += Units;
0215
0216
0217
0218
0219 while (Units--) {
0220 pthread_cond_signal(&ac_sem->wait_cond);
0221 }
0222
0223 pthread_mutex_unlock(&ac_sem->mutex);
0224
0225 return (AE_OK);
0226 }
0227
0228 typedef struct {
0229 pthread_mutex_t mutex;
0230 } acpi_spinlock;
0231
0232 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK* OutHandle)
0233 {
0234 acpi_spinlock* lock;
0235
0236 if (OutHandle == NULL)
0237 return (AE_BAD_PARAMETER);
0238
0239 lock = malloc(sizeof(acpi_spinlock));
0240 if (lock == NULL) {
0241 return (AE_NO_MEMORY);
0242 }
0243
0244 pthread_mutex_init(&lock->mutex, NULL);
0245
0246
0247 *OutHandle = (ACPI_SPINLOCK) lock;
0248
0249 return (AE_OK);
0250 }
0251
0252 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
0253 {
0254 acpi_spinlock* lock = (acpi_spinlock*) Handle;
0255
0256 if (lock == NULL) {
0257 return;
0258 }
0259
0260 pthread_mutex_destroy(&lock->mutex);
0261
0262 free(lock);
0263 }
0264
0265 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
0266 {
0267 acpi_spinlock* lock = (acpi_spinlock*) Handle;
0268
0269 if (lock == NULL) {
0270 return 0;
0271 }
0272
0273 pthread_mutex_lock(&lock->mutex);
0274
0275 return 0;
0276 }
0277
0278 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
0279 {
0280 acpi_spinlock* lock = (acpi_spinlock*) Handle;
0281
0282 if (lock == NULL) {
0283 return;
0284 }
0285
0286 pthread_mutex_unlock(&lock->mutex);
0287 }