--- /dev/null
+#ifndef __PTHREAD_EXTRA_H__
+#define __PTHREAD_EXTRA_H__
+
+#include <pthread.h>
+#include <time.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define PTHREAD_XTIME_NOBLOCK (&(struct timespec){ .tv_sec = 0, .tv_nsec = 0 })
+#define PTHREAD_XTIME_FOREVER NULL
+
+// Message queues
+
+#define PTHREAD_XMQ_FRONT true
+#define PTHREAD_XMQ_BACK false
+
+#define PTHREAD_XMQ_RECV false
+#define PTHREAD_XMQ_PEEK true
+
+typedef struct pthread_mq_t {
+ pthread_mutex_t lock;
+ pthread_cond_t cond_readable;
+ pthread_cond_t cond_writable;
+ void * data;
+ size_t msg_size;
+ size_t msg_count;
+ size_t msg_count_max;
+ size_t head_idx;
+ char * name;
+} pthread_mq_t;
+
+bool pthread_mq_init(pthread_mq_t *mq, size_t msg_size, size_t msg_count_max);
+void pthread_mq_free(pthread_mq_t *mq);
+size_t pthread_mq_waiting(pthread_mq_t *mq);
+bool pthread_mq_reset(pthread_mq_t *mq);
+bool pthread_mq_send_generic(pthread_mq_t *mq, void * data, bool to_front, const struct timespec *restrict abs_timeout);
+bool pthread_mq_receive_generic(pthread_mq_t *mq, void * data, bool peek, const struct timespec *restrict abs_timeout);
+
+// Multi mutex locking
+
+#define pthread_mutex_swap(a, b) ({ pthread_mutex_t *s; s = (a); a = (b); b = s; })
+
+#define pthread_mutex_lock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, NULL)
+#define pthread_mutex_timedlock_two(a,b,tm) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, (tm))
+#define pthread_mutex_trylock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, false, NULL)
+
+#define pthread_mutex_lock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,NULL)
+#define pthread_mutex_timedlock_multi(lcks,cnt,tm) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,(tm))
+#define pthread_mutex_trylock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),false,NULL)
+
+int pthread_mutex_timedlock_multi_generic(pthread_mutex_t **lck, int cnt, bool block, const struct timespec *restrict abs_timeout);
+
+
+#endif //__PTHREAD_EXTRA_H__
-/*
- * CFLAGS=-lpthread make pthread_msgqueue
- */
-
#include <pthread.h>
+#include <pthread_extra.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
-#include <unistd.h>
-
-#define PTHREAD_X_NONWAIT (&(struct timespec){ .tv_sec = 0, .tv_nsec = 0 })
-#define PTHREAD_X_FOREVER NULL
-
-typedef struct pthread_mq_t {
- pthread_mutex_t lock;
- pthread_cond_t cond_readable;
- pthread_cond_t cond_writable;
- void * data;
- size_t msg_size;
- size_t msg_count;
- size_t msg_count_max;
- size_t head_idx;
- char * name;
-} pthread_mq_t;
bool pthread_mq_readable(pthread_mq_t *mq) { return (mq->msg_count > 0); }
bool pthread_mq_writable(pthread_mq_t *mq) { return (mq->msg_count < mq->msg_count_max); }
pthread_mutex_unlock(&mq->lock);
return true;
}
-
-
-
-
-
-
-
-
-
-
-pthread_mq_t myq;
-
-void *thread_recv(void *args) {
- char str[128];
- while(1) {
- pthread_mq_receive_generic(&myq, &str, false, NULL);
- printf("RECVD: %.6s\t\t(waiting %d)\n", str, pthread_mq_waiting(&myq));
- sleep(1);
- }
-}
-
-int main() {
- char tmp[128];
-
- pthread_mq_init(&myq, 6, 5);
-
- pthread_t t;
- pthread_create(&t, NULL, thread_recv, NULL);
-
- pthread_mq_send_generic(&myq, "AHOJ1", false, NULL);
- pthread_mq_send_generic(&myq, "AHOJ2", false, NULL);
- pthread_mq_send_generic(&myq, "AHOJ3", true, NULL);
- pthread_mq_send_generic(&myq, "AHOJ4", true, NULL);
- pthread_mq_send_generic(&myq, "AHOJ5", false, NULL);
- pthread_mq_send_generic(&myq, "AHOJ6", true, NULL);
-
- while(1) {
- pthread_mq_send_generic(&myq, "B", false, NULL);
- pthread_mq_send_generic(&myq, "A", true, NULL);
- pthread_mq_send_generic(&myq, " A", false, NULL);
- pthread_mq_send_generic(&myq, " B", false, NULL);
- }
-
- pthread_join(t, NULL);
-}
-/*
- * CFLAGS=-lpthread make pthread_multi
- */
-
-#include <pthread.h>
+#include <pthread_extra.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>
-#define pthread_mutex_swap(a, b) ({ pthread_mutex_t *s; s = (a); a = (b); b = s; })
-
-#define pthread_mutex_lock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, NULL)
-#define pthread_mutex_timedlock_two(a,b,tm) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, true, (tm))
-#define pthread_mutex_trylock_two(a,b) pthread_mutex_timedlock_multi_generic((pthread_mutex_t *[2]){(a), (b)}, 2, false, NULL)
-
-#define pthread_mutex_lock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,NULL)
-#define pthread_mutex_timedlock_multi(lcks,cnt,tm) pthread_mutex_timedlock_multi_generic((lcks),(cnt),true,(tm))
-#define pthread_mutex_trylock_multi(lcks,cnt) pthread_mutex_timedlock_multi_generic((lcks),(cnt),false,NULL)
-
/*
//This is first prototype for two mutexes only, it is useful in order to understand how this all works
//Currently it was replaced by macro with the same name
pthread_mutex_swap(lck[0],lck[locked]);
}
}
-
-int main() {
- //Prepare mutex array for tests
- static pthread_mutex_t la = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t lb = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t lc = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t ld = PTHREAD_MUTEX_INITIALIZER;
- static pthread_mutex_t *lck[4] = {&la, &lb, &lc, &ld};
-
- //Set timeout
- struct timespec tm;
- clock_gettime(CLOCK_REALTIME, &tm);
- tm.tv_sec += 5;
-
- //Lock one of the locks for testing
- pthread_mutex_lock(lck[2]);
-
- if(!pthread_mutex_timedlock_multi(lck, 4, &tm)) {
- //if(!pthread_mutex_timedlock_two(&la, lck[2], &tm)) {
- printf("LOCKED!\n");
- } else {
- printf("FAILED!\n");
- }
-
-}
--- /dev/null
+#include <pthread.h>
+#include <pthread_extra.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+
+
+int main_mumu() {
+ //Prepare mutex array for tests
+ static pthread_mutex_t la = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_mutex_t lb = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_mutex_t lc = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_mutex_t ld = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_mutex_t *lck[4] = {&la, &lb, &lc, &ld};
+
+ //Set timeout
+ struct timespec tm;
+ clock_gettime(CLOCK_REALTIME, &tm);
+ tm.tv_sec += 5;
+
+ //Lock one of the locks for testing
+ pthread_mutex_lock(lck[2]);
+
+ if(!pthread_mutex_timedlock_multi(lck, 4, &tm)) {
+ //if(!pthread_mutex_timedlock_two(&la, lck[2], &tm)) {
+ printf("LOCKED!\n");
+ } else {
+ printf("FAILED!\n");
+ }
+
+}
+
+
+pthread_mq_t myq;
+
+void *thread_recv(void *args) {
+ char str[128];
+ while(1) {
+ pthread_mq_receive_generic(&myq, &str, false, PTHREAD_XTIME_FOREVER);
+ printf("RECVD: %.6s\t\t(waiting %d)\n", str, pthread_mq_waiting(&myq));
+ //sleep(1);
+ }
+}
+
+int main() {
+ main_mumu();
+
+ char tmp[128];
+
+ pthread_mq_init(&myq, 6, 5);
+
+ pthread_t t;
+ pthread_create(&t, NULL, thread_recv, NULL);
+
+ pthread_mq_send_generic(&myq, "AHOJ1", false, NULL);
+ pthread_mq_send_generic(&myq, "AHOJ2", false, NULL);
+ pthread_mq_send_generic(&myq, "AHOJ3", true, NULL);
+ pthread_mq_send_generic(&myq, "AHOJ4", true, NULL);
+ pthread_mq_send_generic(&myq, "AHOJ5", false, NULL);
+ pthread_mq_send_generic(&myq, "AHOJ6", true, NULL);
+
+ while(1) {
+ pthread_mq_send_generic(&myq, "B", false, NULL);
+ pthread_mq_send_generic(&myq, "A", true, NULL);
+ pthread_mq_send_generic(&myq, " A", false, NULL);
+ pthread_mq_send_generic(&myq, " B", false, NULL);
+ sleep(1);
+ }
+
+ pthread_join(t, NULL);
+}
+