Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lexborisov/Modest.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/myhtml/thread.c')
-rw-r--r--source/myhtml/thread.c1185
1 files changed, 0 insertions, 1185 deletions
diff --git a/source/myhtml/thread.c b/source/myhtml/thread.c
deleted file mode 100644
index 94e277a..0000000
--- a/source/myhtml/thread.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- Copyright (C) 2015-2016 Alexander Borisov
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- Author: lex.borisov@gmail.com (Alexander Borisov)
-*/
-
-#include "myhtml/thread.h"
-
-#ifndef MyHTML_BUILD_WITHOUT_THREADS
-
-#if defined(IS_OS_WINDOWS)
-/***********************************************************************************
- *
- * For Windows
- *
- ***********************************************************************************/
-myhtml_status_t myhtml_thread_create(mythread_t *mythread, mythread_list_t *thr, void *work_func)
-{
- thr->pth = CreateThread(NULL, // default security attributes
- 0, // use default stack size
- work_func, // thread function name
- &thr->data, // argument to thread function
- 0, // use default creation flags
- NULL); // returns the thread identifier
-
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_join(mythread_t *mythread, mythread_list_t *thr)
-{
- WaitForSingleObject(thr->pth, INFINITE);
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_cancel(mythread_t *mythread, mythread_list_t *thr)
-{
- TerminateThread(thr->pth, 0);
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_init(mythread_t *mythread)
-{
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_clean(mythread_t *mythread)
-{
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_destroy(mythread_t *mythread)
-{
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_create(mythread_t *mythread, mythread_context_t *ctx, size_t prefix_id)
-{
- ctx->mutex = CreateSemaphore(NULL, 0, 1, NULL);
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_post(mythread_t *mythread, mythread_context_t *ctx)
-{
- ReleaseSemaphore(ctx->mutex, 1, NULL);
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_wait(mythread_t *mythread, mythread_context_t *ctx)
-{
- WaitForSingleObject(ctx->mutex, INFINITE);
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_try_wait(mythread_t *mythread, mythread_context_t *ctx)
-{
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_close(mythread_t *mythread, mythread_context_t *ctx)
-{
- CloseHandle(ctx->mutex);
-
- return MyHTML_STATUS_OK;
-}
-
-void myhtml_thread_nanosleep(const struct timespec *tomeout)
-{
- Sleep(0);
-}
-
-#else /* defined(IS_OS_WINDOWS) */
-/***********************************************************************************
- *
- * For all unix system. POSIX pthread
- *
- ***********************************************************************************/
-
-myhtml_status_t myhtml_thread_create(mythread_t *mythread, mythread_list_t *thr, void *work_func)
-{
- pthread_create(&thr->pth, mythread->attr,
- work_func,
- (void*)(&thr->data));
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_join(mythread_t *mythread, mythread_list_t *thr)
-{
- pthread_join(thr->pth, NULL);
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_cancel(mythread_t *mythread, mythread_list_t *thr)
-{
- pthread_cancel(thr->pth);
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_init(mythread_t *mythread)
-{
- mythread->attr = (pthread_attr_t*)myhtml_calloc(1, sizeof(pthread_attr_t));
-
- if(mythread->attr == NULL)
- return MyHTML_STATUS_THREAD_ERROR_ATTR_MALLOC;
-
- mythread->sys_last_error = pthread_attr_init(mythread->attr);
- if(mythread->sys_last_error)
- return MyHTML_STATUS_THREAD_ERROR_ATTR_INIT;
-
- mythread->sys_last_error = pthread_attr_setdetachstate(mythread->attr, PTHREAD_CREATE_JOINABLE);
- if(mythread->sys_last_error)
- return MyHTML_STATUS_THREAD_ERROR_ATTR_SET;
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_clean(mythread_t *mythread)
-{
- mythread->attr = NULL;
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_thread_attr_destroy(mythread_t *mythread)
-{
- if(mythread->attr) {
- mythread->sys_last_error = pthread_attr_destroy(mythread->attr);
-
- myhtml_free(mythread->attr);
- mythread->attr = NULL;
-
- if(mythread->sys_last_error)
- return MyHTML_STATUS_THREAD_ERROR_ATTR_DESTROY;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_create(mythread_t *mythread, mythread_context_t *ctx, size_t prefix_id)
-{
- ctx->mutex = (pthread_mutex_t*)myhtml_calloc(1, sizeof(pthread_mutex_t));
-
- if(ctx->mutex == NULL)
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_MALLOC;
-
- if(pthread_mutex_init(ctx->mutex, NULL)) {
- mythread->sys_last_error = errno;
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_INIT;
- }
-
- if(pthread_mutex_lock(ctx->mutex)) {
- mythread->sys_last_error = errno;
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_LOCK;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_post(mythread_t *mythread, mythread_context_t *ctx)
-{
- if(pthread_mutex_unlock(ctx->mutex)) {
- mythread->sys_last_error = errno;
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_UNLOCK;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_wait(mythread_t *mythread, mythread_context_t *ctx)
-{
- if(pthread_mutex_lock(ctx->mutex)) {
- mythread->sys_last_error = errno;
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_LOCK;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_try_wait(mythread_t *mythread, mythread_context_t *ctx)
-{
- if(pthread_mutex_trylock(ctx->mutex)) {
- mythread->sys_last_error = errno;
- return MyHTML_STATUS_THREAD_ERROR_MUTEX_LOCK;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-myhtml_status_t myhtml_hread_mutex_close(mythread_t *mythread, mythread_context_t *ctx)
-{
- if(ctx->mutex) {
- pthread_mutex_destroy(ctx->mutex);
- myhtml_free(ctx->mutex);
-
- ctx->mutex = NULL;
- }
-
- return MyHTML_STATUS_OK;
-}
-
-void myhtml_thread_nanosleep(const struct timespec *tomeout)
-{
- nanosleep(tomeout, NULL);
-}
-
-#endif /* !defined(IS_OS_WINDOWS) */
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-/*
- *
- * MyTHREAD logic
- *
- */
-
-mythread_t * mythread_create(void)
-{
- return myhtml_calloc(1, sizeof(mythread_t));
-}
-
-#ifdef MyHTML_BUILD_WITHOUT_THREADS
-
-myhtml_status_t mythread_init(mythread_t *mythread, const char *sem_prefix, size_t thread_count)
-{
- return MyHTML_STATUS_OK;
-}
-
-#else /* MyHTML_BUILD_WITHOUT_THREADS */
-
-myhtml_status_t mythread_init(mythread_t *mythread, const char *sem_prefix, size_t thread_count)
-{
- mythread->batch_count = 0;
- mythread->batch_first_id = 0;
- mythread->stream_opt = MyTHREAD_OPT_STOP;
- mythread->batch_opt = MyTHREAD_OPT_STOP;
-
- if(thread_count)
- {
- myhtml_status_t status = myhtml_thread_attr_init(mythread);
- if(status)
- return status;
-
- mythread->pth_list_root = 1;
- mythread->pth_list_length = 1;
- mythread->pth_list_size = thread_count + 1;
- mythread->pth_list = (mythread_list_t*)myhtml_calloc(mythread->pth_list_size, sizeof(mythread_list_t));
-
- if(mythread->pth_list == NULL)
- return MyHTML_STATUS_THREAD_ERROR_LIST_INIT;
- }
- else {
- myhtml_thread_attr_clean(mythread);
-
- mythread->sys_last_error = 0;
- mythread->pth_list_root = 1;
- mythread->pth_list_length = 1;
- mythread->pth_list_size = 0;
- mythread->pth_list = NULL;
- }
-
- if(sem_prefix)
- {
- mythread->sem_prefix_length = strlen(sem_prefix);
-
- if(mythread->sem_prefix_length) {
- mythread->sem_prefix = myhtml_calloc((mythread->sem_prefix_length + 1), sizeof(char));
-
- if(mythread->sem_prefix == NULL) {
- mythread->sem_prefix_length = 0;
- return MyHTML_STATUS_THREAD_ERROR_SEM_PREFIX_MALLOC;
- }
-
- myhtml_string_raw_copy(mythread->sem_prefix, sem_prefix, mythread->sem_prefix_length);
- }
- }
-
- return MyHTML_STATUS_OK;
-}
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-void mythread_clean(mythread_t *mythread)
-{
- mythread->sys_last_error = 0;
-}
-
-mythread_t * mythread_destroy(mythread_t *mythread, mythread_callback_before_join_f before_join, bool self_destroy)
-{
- if(mythread == NULL)
- return NULL;
-
-#ifndef MyHTML_BUILD_WITHOUT_THREADS
-
- myhtml_thread_attr_destroy(mythread);
-
- if(mythread->pth_list) {
- mythread_resume_all(mythread);
- mythread_stream_quit_all(mythread);
- mythread_batch_quit_all(mythread);
-
- if(before_join)
- before_join(mythread);
-
- for (size_t i = mythread->pth_list_root; i < mythread->pth_list_length; i++)
- {
- myhtml_thread_join(mythread, &mythread->pth_list[i]);
- }
-
- myhtml_free(mythread->pth_list);
- mythread->pth_list = NULL;
- }
-
- if(mythread->sem_prefix) {
- myhtml_free(mythread->sem_prefix);
-
- mythread->sem_prefix = NULL;
- mythread->sem_prefix_length = 0;
- }
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
- if(self_destroy) {
- myhtml_free(mythread);
- return NULL;
- }
-
- return mythread;
-}
-
-#ifndef MyHTML_BUILD_WITHOUT_THREADS
-
-mythread_id_t _myhread_create_stream_raw(mythread_t *mythread, mythread_work_f work_func, void *process_func, mythread_thread_opt_t opt, myhtml_status_t *status, size_t total_count)
-{
- mythread->sys_last_error = 0;
-
- if(status)
- *status = MyHTML_STATUS_OK;
-
- if(mythread->pth_list_length >= mythread->pth_list_size) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_NO_SLOTS;
-
- return 0;
- }
-
- mythread_list_t *thr = &mythread->pth_list[mythread->pth_list_length];
-
- thr->data.mythread = mythread;
- thr->data.func = work_func;
- thr->data.id = mythread->pth_list_length;
- thr->data.t_count = total_count;
- thr->data.opt = opt;
- thr->data.status = 0;
-
- myhtml_status_t m_status = myhtml_hread_mutex_create(mythread, &thr->data, 0);
-
- if(m_status != MyHTML_STATUS_OK && status) {
- *status = m_status;
- return 0;
- }
-
- m_status = myhtml_thread_create(mythread, thr, process_func);
- if(m_status != MyHTML_STATUS_OK)
- return 0;
-
- mythread->pth_list_length++;
- return thr->data.id;
-}
-
-mythread_id_t myhread_create_stream(mythread_t *mythread, mythread_process_f process_func, mythread_work_f work_func, mythread_thread_opt_t opt, myhtml_status_t *status)
-{
- return _myhread_create_stream_raw(mythread, work_func, process_func, opt, status, 0);
-}
-
-mythread_id_t myhread_create_batch(mythread_t *mythread, mythread_process_f process_func, mythread_work_f work_func, mythread_thread_opt_t opt, myhtml_status_t *status, size_t count)
-{
- if(mythread->batch_count) {
- *status = MyHTML_STATUS_THREAD_ERROR_BATCH_INIT;
- return 0;
- }
- else if((mythread->pth_list_length + count) > mythread->pth_list_size) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_NO_SLOTS;
-
- return 0;
- }
-
- if(count == 0)
- count = 1;
-
- mythread->batch_first_id = 0;
- mythread->batch_count = count;
-
- size_t start = mythread->pth_list_length;
- *status = MyHTML_STATUS_OK;
-
- bool init_first = false;
-
- for (size_t i = 0; i < count; i++)
- {
- mythread_id_t curr_id = _myhread_create_stream_raw(mythread, work_func, process_func, opt, status, i);
-
- if(init_first == false) {
- mythread->batch_first_id = curr_id;
- init_first = true;
- }
-
- if(*status)
- {
- for (size_t n = start; n < (start + i); n++)
- {
- mythread_list_t *thr = &mythread->pth_list[n];
-
- myhtml_thread_cancel(mythread, thr);
-
- myhtml_hread_mutex_post(mythread, &thr->data);
- myhtml_hread_mutex_close(mythread, &thr->data);
- }
-
- mythread->batch_first_id = 0;
- mythread->batch_count = 0;
-
- break;
- }
- }
-
- return mythread->batch_first_id;
-}
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-// mythread queue functions
-#ifndef MyHTML_BUILD_WITHOUT_THREADS
-mythread_queue_list_t * mythread_queue_list_create(myhtml_status_t *status)
-{
- if(status)
- *status = MyHTML_STATUS_OK;
-
- mythread_queue_list_t* queue_list = (mythread_queue_list_t*)myhtml_calloc(1, sizeof(mythread_queue_list_t));
-
- if(queue_list == NULL) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_MALLOC;
- return NULL;
- }
-
- return queue_list;
-}
-
-void mythread_queue_list_destroy(mythread_queue_list_t* queue_list)
-{
- if(queue_list == NULL)
- return;
-
- myhtml_free(queue_list);
-}
-
-size_t mythread_queue_list_get_count(mythread_queue_list_t* queue_list)
-{
- return queue_list->count;
-}
-
-mythread_queue_list_entry_t * mythread_queue_list_entry_push(mythread_t *mythread, mythread_queue_t *queue, myhtml_status_t *status)
-{
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
-
- if(status)
- *status = MyHTML_STATUS_OK;
-
- mythread_queue_list_entry_t* entry = (mythread_queue_list_entry_t*)myhtml_calloc(1, sizeof(mythread_queue_list_entry_t));
-
- if(entry == NULL) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_MALLOC;
- return NULL;
- }
-
- entry->thread_param = (mythread_queue_thread_param_t*)myhtml_calloc(mythread->pth_list_size, sizeof(mythread_queue_thread_param_t));
-
- if(entry->thread_param == NULL) {
- myhtml_free(entry);
-
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_MALLOC;
- return NULL;
- }
-
- size_t idx;
- for (idx = mythread->batch_first_id; idx < (mythread->batch_first_id + mythread->batch_count); idx++) {
- entry->thread_param[idx].use = mythread->pth_list[idx].data.t_count;
- }
-
- entry->queue = queue;
-
- if(mythread->stream_opt == MyTHREAD_OPT_UNDEF) {
- mythread_suspend_all(mythread);
- }
- else if(mythread->stream_opt == MyTHREAD_OPT_STOP) {
- mythread_stop_all(mythread);
- }
-
- if(queue_list->first) {
- queue_list->last->next = entry;
- entry->prev = queue_list->last;
-
- queue_list->last = entry;
- }
- else {
- queue_list->first = entry;
- queue_list->last = entry;
- }
-
- queue_list->count++;
-
- if(mythread->stream_opt != MyTHREAD_OPT_STOP)
- mythread_resume_all(mythread);
-
- return entry;
-}
-
-mythread_queue_list_entry_t * mythread_queue_list_entry_delete(mythread_t *mythread, mythread_queue_list_entry_t *entry, bool destroy_queue)
-{
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
-
- mythread_queue_list_entry_t *next = entry->next;
- mythread_queue_list_entry_t *prev = entry->prev;
-
- if(mythread->stream_opt == MyTHREAD_OPT_UNDEF) {
- mythread_suspend_all(mythread);
- }
- else if(mythread->stream_opt == MyTHREAD_OPT_STOP) {
- mythread_stop_all(mythread);
- }
-
- if(prev)
- prev->next = next;
-
- if(next)
- next->prev = prev;
-
- if(queue_list->first == entry)
- queue_list->first = next;
-
- if(queue_list->last == entry)
- queue_list->last = prev;
-
- if(mythread->stream_opt != MyTHREAD_OPT_STOP)
- mythread_resume_all(mythread);
-
- if(destroy_queue && entry->queue)
- mythread_queue_destroy(entry->queue);
-
- if(entry->thread_param)
- myhtml_free(entry->thread_param);
-
- myhtml_free(entry);
-
- queue_list->count--;
-
- return NULL;
-}
-
-void mythread_queue_list_entry_clean(mythread_t *mythread, mythread_queue_list_entry_t *entry)
-{
- if(entry == NULL)
- return;
-
- mythread_queue_clean(entry->queue);
-
- size_t idx;
- for (idx = mythread->pth_list_root; idx < mythread->batch_first_id; idx++) {
- entry->thread_param[idx].use = 0;
- }
-
- for (idx = mythread->batch_first_id; idx < (mythread->batch_first_id + mythread->batch_count); idx++) {
- entry->thread_param[idx].use = mythread->pth_list[idx].data.t_count;
- }
-}
-
-void mythread_queue_list_entry_wait_for_done(mythread_t *mythread, mythread_queue_list_entry_t *entry)
-{
- if(entry == NULL)
- return;
-
- size_t idx;
- const struct timespec tomeout = {0, 0};
-
- for (idx = mythread->pth_list_root; idx < mythread->pth_list_size; idx++) {
- mythread_queue_thread_param_t *thread_param = &entry->thread_param[ idx ];
- while(thread_param->use < entry->queue->nodes_uses) {
- myhtml_thread_nanosleep(&tomeout);
- }
- }
-}
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-mythread_queue_t * mythread_queue_create(size_t size, myhtml_status_t *status)
-{
- if(status)
- *status = MyHTML_STATUS_OK;
-
- if(size < 4096)
- size = 4096;
-
- mythread_queue_t* queue = (mythread_queue_t*)myhtml_malloc(sizeof(mythread_queue_t));
-
- if(queue == NULL) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_MALLOC;
- return NULL;
- }
-
- queue->nodes_pos_size = 512;
- queue->nodes_size = size;
- queue->nodes = (mythread_queue_node_t**)myhtml_calloc(queue->nodes_pos_size, sizeof(mythread_queue_node_t*));
-
- if(queue->nodes == NULL) {
- myhtml_free(queue);
-
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODES_MALLOC;
- return NULL;
- }
-
- mythread_queue_clean(queue);
-
- queue->nodes[queue->nodes_pos] = (mythread_queue_node_t*)myhtml_malloc(sizeof(mythread_queue_node_t) * queue->nodes_size);
-
- if(queue->nodes[queue->nodes_pos] == NULL) {
- myhtml_free(queue->nodes);
- myhtml_free(queue);
-
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODE_MALLOC;
- return NULL;
- }
-
- return queue;
-}
-
-void mythread_queue_clean(mythread_queue_t* queue)
-{
- queue->nodes_length = 0;
- queue->nodes_pos = 0;
- queue->nodes_root = 0;
- queue->nodes_uses = 0;
-
- if(queue->nodes[queue->nodes_pos])
- mythread_queue_node_clean(&queue->nodes[queue->nodes_pos][queue->nodes_length]);
-}
-
-mythread_queue_t * mythread_queue_destroy(mythread_queue_t* queue)
-{
- if(queue == NULL)
- return NULL;
-
- if(queue->nodes) {
- for (size_t i = 0; i <= queue->nodes_pos; i++) {
- myhtml_free(queue->nodes[i]);
- }
-
- myhtml_free(queue->nodes);
- }
-
- myhtml_free(queue);
-
- return NULL;
-}
-
-void mythread_queue_node_clean(mythread_queue_node_t* qnode)
-{
- memset(qnode, 0, sizeof(mythread_queue_node_t));
-}
-
-mythread_queue_node_t * mythread_queue_get_prev_node(mythread_queue_node_t* qnode)
-{
- return qnode->prev;
-}
-
-mythread_queue_node_t * mythread_queue_get_current_node(mythread_queue_t* queue)
-{
- return &queue->nodes[queue->nodes_pos][queue->nodes_length];
-}
-
-mythread_queue_node_t * mythread_queue_get_first_node(mythread_queue_t* queue)
-{
- return &queue->nodes[0][0];
-}
-
-size_t mythread_queue_count_used_node(mythread_queue_t* queue)
-{
- return queue->nodes_uses;
-}
-
-mythread_queue_node_t * mythread_queue_node_malloc(mythread_t *mythread, mythread_queue_t* queue, myhtml_status_t *status)
-{
- queue->nodes_length++;
-
- if(queue->nodes_length >= queue->nodes_size)
- {
- queue->nodes_pos++;
-
- if(queue->nodes_pos >= queue->nodes_pos_size)
- {
- mythread_queue_wait_all_for_done(mythread);
-
- queue->nodes_pos_size <<= 1;
- mythread_queue_node_t** tmp = myhtml_realloc(queue->nodes, sizeof(mythread_queue_node_t*) * queue->nodes_pos_size);
-
- if(tmp) {
- memset(&tmp[queue->nodes_pos], 0, sizeof(mythread_queue_node_t*) * (queue->nodes_pos_size - queue->nodes_pos));
-
- queue->nodes = tmp;
- }
- else {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODES_MALLOC;
-
- return NULL;
- }
- }
-
- if(queue->nodes[queue->nodes_pos] == NULL) {
- queue->nodes[queue->nodes_pos] = (mythread_queue_node_t*)myhtml_malloc(sizeof(mythread_queue_node_t) * queue->nodes_size);
-
- if(queue->nodes[queue->nodes_pos] == NULL) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODE_MALLOC;
-
- return NULL;
- }
- }
-
- queue->nodes_length = 0;
- }
-
- queue->nodes_uses++;
-
- return &queue->nodes[queue->nodes_pos][queue->nodes_length];
-}
-
-mythread_queue_node_t * mythread_queue_node_malloc_limit(mythread_t *mythread, mythread_queue_t* queue, size_t limit, myhtml_status_t *status)
-{
- queue->nodes_length++;
-
- if(queue->nodes_uses >= limit) {
- queue->nodes_uses++;
- mythread_queue_wait_all_for_done(mythread);
-
- queue->nodes_length = 0;
- queue->nodes_pos = 0;
- queue->nodes_root = 0;
- queue->nodes_uses = 0;
- }
- else if(queue->nodes_length >= queue->nodes_size)
- {
- queue->nodes_pos++;
-
- if(queue->nodes_pos >= queue->nodes_pos_size)
- {
- mythread_queue_wait_all_for_done(mythread);
-
- queue->nodes_pos_size <<= 1;
- mythread_queue_node_t** tmp = myhtml_realloc(queue->nodes, sizeof(mythread_queue_node_t*) * queue->nodes_pos_size);
-
- if(tmp) {
- memset(&tmp[queue->nodes_pos], 0, sizeof(mythread_queue_node_t*) * (queue->nodes_pos_size - queue->nodes_pos));
-
- queue->nodes = tmp;
- }
- else {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODES_MALLOC;
-
- return NULL;
- }
- }
-
- if(queue->nodes[queue->nodes_pos] == NULL) {
- queue->nodes[queue->nodes_pos] = (mythread_queue_node_t*)myhtml_malloc(sizeof(mythread_queue_node_t) * queue->nodes_size);
-
- if(queue->nodes[queue->nodes_pos] == NULL) {
- if(status)
- *status = MyHTML_STATUS_THREAD_ERROR_QUEUE_NODE_MALLOC;
-
- return NULL;
- }
- }
-
- queue->nodes_length = 0;
- }
-
- queue->nodes_uses++;
-
- return &queue->nodes[queue->nodes_pos][queue->nodes_length];
-}
-
-#ifndef MyHTML_BUILD_WITHOUT_THREADS
-
-mythread_queue_node_t * mythread_queue_node_malloc_round(mythread_t *mythread, mythread_queue_list_entry_t *entry, myhtml_status_t *status)
-{
- mythread_queue_t* queue = entry->queue;
-
- queue->nodes_length++;
-
- if(queue->nodes_length >= queue->nodes_size) {
- queue->nodes_uses++;
-
- mythread_queue_list_entry_wait_for_done(mythread, entry);
- mythread_queue_list_entry_clean(mythread, entry);
- }
- else
- queue->nodes_uses++;
-
- return &queue->nodes[queue->nodes_pos][queue->nodes_length];
-}
-
-void mythread_queue_wait_all_for_done(mythread_t *mythread)
-{
- const struct timespec tomeout = {0, 0};
-
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
- mythread_queue_list_entry_t *entry = queue_list->first;
-
- while(entry)
- {
- for (size_t idx = mythread->pth_list_root; idx < mythread->pth_list_size; idx++) {
- while(entry->thread_param[idx].use < entry->queue->nodes_uses) {
- myhtml_thread_nanosleep(&tomeout);
- }
- }
-
- entry = entry->next;
- }
-}
-
-#else
-
-void mythread_queue_wait_all_for_done(mythread_t *mythread) {}
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-#ifdef MyHTML_BUILD_WITHOUT_THREADS
-
-void mythread_stream_quit_all(mythread_t *mythread) {}
-void mythread_batch_quit_all(mythread_t *mythread) {}
-void mythread_stream_stop_all(mythread_t *mythread) {}
-void mythread_batch_stop_all(mythread_t *mythread) {}
-void mythread_stop_all(mythread_t *mythread) {}
-void mythread_resume_all(mythread_t *mythread) {}
-void mythread_suspend_all(mythread_t *mythread) {}
-
-#else /* MyHTML_BUILD_WITHOUT_THREADS */
-
-// mythread functions
-void mythread_stream_quit_all(mythread_t *mythread)
-{
- mythread->stream_opt = MyTHREAD_OPT_QUIT;
-}
-
-void mythread_batch_quit_all(mythread_t *mythread)
-{
- mythread->batch_opt = MyTHREAD_OPT_QUIT;
-}
-
-void mythread_stream_stop_all(mythread_t *mythread)
-{
- if(mythread->stream_opt != MyTHREAD_OPT_STOP)
- mythread->stream_opt = MyTHREAD_OPT_STOP;
-
- size_t idx;
- const struct timespec tomeout = {0, 0};
-
- for (idx = mythread->pth_list_root; idx < mythread->batch_first_id; idx++) {
- while(mythread->pth_list[idx].data.opt != MyTHREAD_OPT_STOP) {
- myhtml_thread_nanosleep(&tomeout);
- }
- }
-}
-
-void mythread_batch_stop_all(mythread_t *mythread)
-{
- if(mythread->batch_opt != MyTHREAD_OPT_STOP)
- mythread->batch_opt = MyTHREAD_OPT_STOP;
-
- size_t idx;
- const struct timespec tomeout = {0, 0};
-
- for (idx = mythread->batch_first_id; idx < (mythread->batch_first_id + mythread->batch_count); idx++) {
- while(mythread->pth_list[idx].data.opt != MyTHREAD_OPT_STOP) {
- myhtml_thread_nanosleep(&tomeout);
- }
- }
-}
-
-void mythread_stop_all(mythread_t *mythread)
-{
- mythread_stream_stop_all(mythread);
- mythread_batch_stop_all(mythread);
-}
-
-void mythread_resume_all(mythread_t *mythread)
-{
- if(mythread->stream_opt == MyTHREAD_OPT_UNDEF &&
- mythread->batch_opt == MyTHREAD_OPT_UNDEF)
- return;
-
- if(mythread->stream_opt == MyTHREAD_OPT_WAIT ||
- mythread->batch_opt == MyTHREAD_OPT_WAIT)
- {
- mythread->stream_opt = MyTHREAD_OPT_UNDEF;
- mythread->batch_opt = MyTHREAD_OPT_UNDEF;
- }
- else {
- mythread->stream_opt = MyTHREAD_OPT_UNDEF;
- mythread->batch_opt = MyTHREAD_OPT_UNDEF;
-
- for (size_t idx = mythread->pth_list_root; idx < mythread->pth_list_size; idx++) {
- myhtml_hread_mutex_post(mythread, &mythread->pth_list[idx].data);
- }
- }
-}
-
-void mythread_suspend_all(mythread_t *mythread)
-{
- if(mythread->stream_opt != MyTHREAD_OPT_WAIT)
- mythread->stream_opt = MyTHREAD_OPT_WAIT;
-
- if(mythread->batch_opt != MyTHREAD_OPT_WAIT)
- mythread->batch_opt = MyTHREAD_OPT_WAIT;
-
- const struct timespec tomeout = {0, 0};
-
- for (size_t idx = mythread->pth_list_root; idx < mythread->pth_list_size; idx++) {
- myhtml_hread_mutex_try_wait(mythread, &mythread->pth_list[idx].data);
-
- while(mythread->pth_list[idx].data.opt != MyTHREAD_OPT_WAIT) {
- myhtml_thread_nanosleep(&tomeout);
- }
- }
-}
-
-unsigned int mythread_check_status(mythread_t *mythread)
-{
- for (size_t idx = mythread->pth_list_root; idx < mythread->pth_list_size; idx++) {
- if(mythread->pth_list[idx].data.status) {
- return mythread->pth_list[idx].data.status;
- }
- }
-
- return MyHTML_STATUS_OK;
-}
-
-bool mythread_function_see_for_all_done(mythread_queue_list_t *queue_list, size_t thread_id)
-{
- size_t done_count = 0;
-
- mythread_queue_list_entry_t *entry = queue_list->first;
- while(entry)
- {
- if(entry->thread_param[ thread_id ].use >= entry->queue->nodes_uses) {
- done_count++;
- entry = entry->next;
- }
- else
- break;
- }
-
- return done_count == queue_list->count;
-}
-
-bool mythread_function_see_opt(mythread_context_t *ctx, volatile mythread_thread_opt_t opt, size_t done_count, const struct timespec *timeout)
-{
- mythread_t * mythread = ctx->mythread;
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
-
- if(done_count != queue_list->count)
- return false;
-
- if(opt & MyTHREAD_OPT_STOP)
- {
- if(mythread_function_see_for_all_done(queue_list, ctx->id))
- {
- ctx->opt = MyTHREAD_OPT_STOP;
- myhtml_hread_mutex_wait(mythread, ctx);
- ctx->opt = MyTHREAD_OPT_UNDEF;
-
- return false;
- }
- }
- else if(opt & MyTHREAD_OPT_QUIT)
- {
- if(mythread_function_see_for_all_done(queue_list, ctx->id))
- {
- myhtml_hread_mutex_close(mythread, ctx);
- ctx->opt = MyTHREAD_OPT_QUIT;
- return true;
- }
- }
-
- myhtml_thread_nanosleep(timeout);
-
- return false;
-}
-
-void mythread_function_queue_batch(void *arg)
-{
- mythread_context_t *ctx = (mythread_context_t*)arg;
- mythread_t * mythread = ctx->mythread;
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
-
- const struct timespec timeout = {0, 0};
- myhtml_hread_mutex_wait(mythread, ctx);
-
- do {
- if(mythread->batch_opt & MyTHREAD_OPT_WAIT) {
- ctx->opt = MyTHREAD_OPT_WAIT;
-
- while (mythread->batch_opt & MyTHREAD_OPT_WAIT) {
- myhtml_thread_nanosleep(&timeout);
- }
-
- ctx->opt = MyTHREAD_OPT_UNDEF;
- }
-
- mythread_queue_list_entry_t *entry = queue_list->first;
- size_t done_count = 0;
-
- while(entry)
- {
- mythread_queue_thread_param_t *thread_param = &entry->thread_param[ ctx->id ];
-
- if(thread_param->use < entry->queue->nodes_uses)
- {
- size_t pos = thread_param->use / entry->queue->nodes_size;
- size_t len = thread_param->use % entry->queue->nodes_size;
-
- mythread_queue_node_t *qnode = &entry->queue->nodes[pos][len];
-
- if((qnode->tree->flags & MyHTML_TREE_FLAGS_SINGLE_MODE) == 0)
- ctx->func(ctx->id, (void*)qnode);
-
- thread_param->use += mythread->batch_count;
- }
- else
- done_count++;
-
- entry = entry->next;
- }
-
- if(done_count == queue_list->count &&
- mythread_function_see_opt(ctx, mythread->batch_opt, done_count, &timeout))
- break;
- }
- while (1);
-}
-
-void mythread_function_queue_stream(void *arg)
-{
- mythread_context_t *ctx = (mythread_context_t*)arg;
- mythread_t * mythread = ctx->mythread;
- mythread_queue_list_t *queue_list = (mythread_queue_list_t*)mythread->context;
-
- const struct timespec timeout = {0, 0};
- myhtml_hread_mutex_wait(mythread, ctx);
-
- do {
- if(mythread->stream_opt & MyTHREAD_OPT_WAIT) {
- ctx->opt = MyTHREAD_OPT_WAIT;
-
- while (mythread->stream_opt & MyTHREAD_OPT_WAIT) {
- myhtml_thread_nanosleep(&timeout);
- }
-
- ctx->opt = MyTHREAD_OPT_UNDEF;
- }
-
- mythread_queue_list_entry_t *entry = queue_list->first;
- size_t done_count = 0;
-
- while(entry)
- {
- mythread_queue_thread_param_t *thread_param = &entry->thread_param[ ctx->id ];
-
- if(thread_param->use < entry->queue->nodes_uses)
- {
- size_t pos = thread_param->use / entry->queue->nodes_size;
- size_t len = thread_param->use % entry->queue->nodes_size;
-
- mythread_queue_node_t *qnode = &entry->queue->nodes[pos][len];
-
- if((qnode->tree->flags & MyHTML_TREE_FLAGS_SINGLE_MODE) == 0)
- ctx->func(ctx->id, (void*)qnode);
-
- thread_param->use++;
- }
- else
- done_count++;
-
- entry = entry->next;
- }
-
- if(done_count == queue_list->count &&
- mythread_function_see_opt(ctx, mythread->stream_opt, done_count, &timeout))
- break;
- }
- while (1);
-}
-
-void mythread_function(void *arg)
-{
- mythread_context_t *ctx = (mythread_context_t*)arg;
- mythread_t * mythread = ctx->mythread;
-
- myhtml_hread_mutex_wait(mythread, ctx);
-
- do {
- if(mythread->stream_opt & MyTHREAD_OPT_STOP || ctx->opt & MyTHREAD_OPT_STOP)
- {
- ctx->opt |= MyTHREAD_OPT_DONE;
- myhtml_hread_mutex_wait(mythread, ctx);
-
- if(mythread->stream_opt & MyTHREAD_OPT_QUIT || ctx->opt & MyTHREAD_OPT_QUIT)
- {
- myhtml_hread_mutex_close(mythread, ctx);
- ctx->opt = MyTHREAD_OPT_QUIT;
- break;
- }
-
- ctx->opt = MyTHREAD_OPT_UNDEF;
- }
- else if(mythread->stream_opt & MyTHREAD_OPT_QUIT || ctx->opt & MyTHREAD_OPT_QUIT)
- {
- myhtml_hread_mutex_close(mythread, ctx);
- ctx->opt = MyTHREAD_OPT_QUIT;
- break;
- }
-
- ctx->func(ctx->id, ctx);
- }
- while (1);
-}
-
-#endif /* MyHTML_BUILD_WITHOUT_THREADS */
-
-