Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers equeue_posix.c Source File

equeue_posix.c

00001 /*
00002  * Implementation for Posix compliant platforms
00003  *
00004  * Copyright (c) 2016 Christopher Haster
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 #include "equeue/equeue_platform.h"
00019 
00020 #if defined(EQUEUE_PLATFORM_POSIX)
00021 
00022 #include <time.h>
00023 #include <sys/time.h>
00024 #include <errno.h>
00025 
00026 
00027 // Tick operations
00028 unsigned equeue_tick(void) {
00029     struct timeval tv;
00030     gettimeofday(&tv, 0);
00031     return (unsigned)(tv.tv_sec*1000 + tv.tv_usec/1000);
00032 }
00033 
00034 
00035 // Mutex operations
00036 int equeue_mutex_create(equeue_mutex_t *m) {
00037     return pthread_mutex_init(m, 0);
00038 }
00039 
00040 void equeue_mutex_destroy(equeue_mutex_t *m) {
00041     pthread_mutex_destroy(m);
00042 }
00043 
00044 void equeue_mutex_lock(equeue_mutex_t *m) {
00045     pthread_mutex_lock(m);
00046 }
00047 
00048 void equeue_mutex_unlock(equeue_mutex_t *m) {
00049     pthread_mutex_unlock(m);
00050 }
00051 
00052 
00053 // Semaphore operations
00054 int equeue_sema_create(equeue_sema_t *s) {
00055     int err = pthread_mutex_init(&s->mutex, 0);
00056     if (err) {
00057         return err;
00058     }
00059 
00060     err = pthread_cond_init(&s->cond, 0);
00061     if (err) {
00062         return err;
00063     }
00064 
00065     s->signal = false;
00066     return 0;
00067 }
00068 
00069 void equeue_sema_destroy(equeue_sema_t *s) {
00070     pthread_cond_destroy(&s->cond);
00071     pthread_mutex_destroy(&s->mutex);
00072 }
00073 
00074 void equeue_sema_signal(equeue_sema_t *s) {
00075     pthread_mutex_lock(&s->mutex);
00076     s->signal = true;
00077     pthread_cond_signal(&s->cond);
00078     pthread_mutex_unlock(&s->mutex);
00079 }
00080 
00081 bool equeue_sema_wait(equeue_sema_t *s, int ms) {
00082     pthread_mutex_lock(&s->mutex);
00083     if (!s->signal) {
00084         if (ms < 0) {
00085             pthread_cond_wait(&s->cond, &s->mutex);
00086         } else {
00087             struct timeval tv;
00088             gettimeofday(&tv, 0);
00089 
00090             struct timespec ts = {
00091                 .tv_sec = ms/1000 + tv.tv_sec,
00092                 .tv_nsec = ms*1000000 + tv.tv_usec*1000,
00093             };
00094 
00095             pthread_cond_timedwait(&s->cond, &s->mutex, &ts);
00096         }
00097     }
00098 
00099     bool signal = s->signal;
00100     s->signal = false;
00101     pthread_mutex_unlock(&s->mutex);
00102 
00103     return signal;
00104 }
00105 
00106 #endif