1 /*
2  Copyright (C) 2015-2017 Alexander Borisov
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 
18  Author: lex.borisov@gmail.com (Alexander Borisov)
19 */
20 
21 #ifndef MyCORE_THREAD_H
22 #define MyCORE_THREAD_H
23 #pragma once
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #include <mycore/myosi.h>
30 #include <mycore/mystring.h>
31 
32 #ifdef MyCORE_BUILD_WITHOUT_THREADS
33 
34 struct mythread {
35     int sys_last_error;
36 };
37 
38 #else
39 /* functions */
40 typedef void (*mythread_callback_before_entry_join_f)(mythread_t* mythread, mythread_entry_t* entry, void* ctx);
41 typedef void * (*mythread_process_f)(void* arg);
42 typedef void (*mythread_work_f)(mythread_id_t thread_id, void* arg);
43 
44 void * mythread_function_queue_stream(void *arg);
45 void * mythread_function_queue_batch(void *arg);
46 void * mythread_function(void *arg);
47 
48 enum mythread_thread_opt {
49     MyTHREAD_OPT_UNDEF = 0x00,
50     MyTHREAD_OPT_WAIT  = 0x01,
51     MyTHREAD_OPT_QUIT  = 0x02,
52     MyTHREAD_OPT_STOP  = 0x04,
53     MyTHREAD_OPT_DONE  = 0x08
54 }
55 typedef mythread_thread_opt_t;
56 
57 enum mythread_type {
58     MyTHREAD_TYPE_STREAM = 0x00,
59     MyTHREAD_TYPE_BATCH  = 0x01
60 }
61 typedef mythread_type_t;
62 
63 // thread
64 struct mythread_context {
65     mythread_id_t id;
66     mythread_work_f func;
67 
68     volatile size_t t_count;
69     volatile mythread_thread_opt_t opt;
70 
71     mystatus_t status;
72 
73     void* mutex;
74     void* timespec;
75     mythread_t* mythread;
76 };
77 
78 struct mythread_entry {
79     void* thread;
80 
81     mythread_context_t context;
82     mythread_process_f process_func;
83 };
84 
85 struct mythread {
86     mythread_entry_t *entries;
87     size_t entries_length;
88     size_t entries_size;
89     size_t id_increase;
90 
91     void* context;
92     void* attr;
93     void* timespec;
94 
95     int sys_last_error;
96 
97     mythread_type_t type;
98     volatile mythread_thread_opt_t opt;
99 };
100 
101 mythread_t * mythread_create(void);
102 mystatus_t mythread_init(mythread_t *mythread, mythread_type_t type, size_t threads_count, size_t id_increase);
103 void mythread_clean(mythread_t *mythread);
104 mythread_t * mythread_destroy(mythread_t *mythread, mythread_callback_before_entry_join_f before_join, void* ctx, bool self_destroy);
105 
106 mythread_id_t myhread_increase_id_by_entry_id(mythread_t* mythread, mythread_id_t thread_id);
107 
108 /* set for all threads */
109 mystatus_t mythread_join(mythread_t *mythread, mythread_callback_before_entry_join_f before_join, void* ctx);
110 mystatus_t mythread_quit(mythread_t *mythread, mythread_callback_before_entry_join_f before_join, void* ctx);
111 mystatus_t mythread_stop(mythread_t *mythread);
112 mystatus_t mythread_resume(mythread_t *mythread, mythread_thread_opt_t send_opt);
113 mystatus_t mythread_suspend(mythread_t *mythread);
114 mystatus_t mythread_check_status(mythread_t *mythread);
115 
116 mythread_thread_opt_t mythread_option(mythread_t *mythread);
117 void mythread_option_set(mythread_t *mythread, mythread_thread_opt_t opt);
118 
119 /* Entries */
120 mystatus_t myhread_entry_create(mythread_t *mythread, mythread_process_f process_func, mythread_work_f func, mythread_thread_opt_t opt);
121 
122 mystatus_t mythread_entry_join(mythread_entry_t* entry, mythread_callback_before_entry_join_f before_join, void* ctx);
123 mystatus_t mythread_entry_quit(mythread_entry_t* entry, mythread_callback_before_entry_join_f before_join, void* ctx);
124 mystatus_t mythread_entry_stop(mythread_entry_t* entry);
125 mystatus_t mythread_entry_resume(mythread_entry_t* entry, mythread_thread_opt_t send_opt);
126 mystatus_t mythread_entry_suspend(mythread_entry_t* entry);
127 mystatus_t mythread_entry_status(mythread_entry_t* entry);
128 mythread_t * mythread_entry_mythread(mythread_entry_t* entry);
129 
130 /* API for ports */
131 void * mythread_thread_create(mythread_t *mythread, mythread_process_f process_func, void* ctx);
132 mystatus_t mythread_thread_join(mythread_t *mythread, void* thread);
133 mystatus_t mythread_thread_cancel(mythread_t *mythread, void* thread);
134 mystatus_t mythread_thread_destroy(mythread_t *mythread, void* thread);
135 
136 void * mythread_thread_attr_init(mythread_t *mythread);
137 void mythread_thread_attr_clean(mythread_t *mythread, void* attr);
138 void mythread_thread_attr_destroy(mythread_t *mythread, void* attr);
139 
140 void * mythread_mutex_create(mythread_t *mythread);
141 mystatus_t mythread_mutex_post(mythread_t *mythread, void* mutex);
142 mystatus_t mythread_mutex_wait(mythread_t *mythread, void* mutex);
143 void mythread_mutex_close(mythread_t *mythread, void* mutex);
144 
145 void * mythread_nanosleep_create(mythread_t* mythread);
146 void mythread_nanosleep_clean(void* timespec);
147 void mythread_nanosleep_destroy(void* timespec);
148 mystatus_t mythread_nanosleep_sleep(void* timespec);
149 
150 /* callback */
151 void mythread_callback_quit(mythread_t* mythread, mythread_entry_t* entry, void* ctx);
152 
153 #endif
154 
155 #ifdef __cplusplus
156 } /* extern "C" */
157 #endif
158 
159 #endif /* MyCORE_THREAD_H */
160