void mchar_async_init(mchar_async_t *mchar_async, size_t chunk_len, size_t char_size) { if(char_size < 4096) char_size = 4096; mchar_async->origin_size = char_size; mchar_async->chunks_size = chunk_len; mchar_async->chunks_pos_size = 1024; mchar_async->chunks = (mchar_async_chunk_t**)myhtml_calloc(mchar_async->chunks_pos_size, sizeof(mchar_async_chunk_t*)); mchar_async->chunks[0] = (mchar_async_chunk_t*)myhtml_calloc(mchar_async->chunks_size, sizeof(mchar_async_chunk_t)); mchar_async_cache_init(&mchar_async->chunk_cache); mchar_async->nodes_length = 0; mchar_async->nodes_size = 64; mchar_async->nodes = (mchar_async_node_t*)myhtml_calloc(mchar_async->nodes_size, sizeof(mchar_async_node_t)); mchar_async->nodes_cache_length = 0; mchar_async->nodes_cache_size = mchar_async->nodes_size; mchar_async->nodes_cache = (size_t*)myhtml_malloc(mchar_async->nodes_cache_size * sizeof(size_t)); mchar_async_clean(mchar_async); mchar_async->mcsync = mcsync_create(); }
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; 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; }
myhtml_status_t mythread_init(mythread_t *mythread, const char *sem_prefix, size_t thread_count, size_t queue_size) { 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; } myhtml_status_t status; mythread->queue_list = mythread_queue_list_create(mythread, &status); if(mythread->queue_list == NULL) return status; 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; }
mchar_async_t * mchar_async_create(size_t pos_size, size_t size) { mchar_async_t *mcobj_async = (mchar_async_t*)myhtml_calloc(1, sizeof(mchar_async_t)); mchar_async_init(mcobj_async, pos_size, size); return mcobj_async; }
mythread_queue_list_t * mythread_queue_list_create(mythread_t *mythread, 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; }
mchar_async_chunk_t * mchar_async_chunk_malloc_without_lock(mchar_async_t *mchar_async, mchar_async_node_t *node, size_t length) { if(mchar_async_cache_has_nodes(mchar_async->chunk_cache)) { size_t index = mchar_async_cache_delete(&mchar_async->chunk_cache, length); if(index) return (mchar_async_chunk_t*)mchar_async->chunk_cache.nodes[index].value; } if(mchar_async->chunks_length >= mchar_async->chunks_size) { size_t current_idx = mchar_async->chunks_pos_length; mchar_async->chunks_pos_length++; if(mchar_async->chunks_pos_length >= mchar_async->chunks_pos_size) { mchar_async->chunks_pos_size <<= 1; mchar_async_chunk_t **tmp_pos = myhtml_realloc(mchar_async->chunks, sizeof(mchar_async_chunk_t*) * mchar_async->chunks_pos_size); if(tmp_pos) { memset(&tmp_pos[mchar_async->chunks_pos_length], 0, (mchar_async->chunks_pos_size - mchar_async->chunks_pos_length) * sizeof(mchar_async_chunk_t*)); mchar_async->chunks = tmp_pos; } } if(mchar_async->chunks[current_idx] == NULL) { mchar_async_chunk_t *tmp = myhtml_calloc(mchar_async->chunks_size, sizeof(mchar_async_chunk_t)); if(tmp) mchar_async->chunks[current_idx] = tmp; } mchar_async->chunks_length = 0; } mchar_async_chunk_t *chunk = &mchar_async->chunks[mchar_async->chunks_pos_length - 1][mchar_async->chunks_length]; mchar_async->chunks_length++; mchar_async_mem_malloc(mchar_async, node, chunk, length); return chunk; }
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; }
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; }
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; }
mythread_t * mythread_create(void) { return myhtml_calloc(1, sizeof(mythread_t)); }
mycss_stylesheet_t * mycss_stylesheet_create(void) { return (mycss_stylesheet_t*)myhtml_calloc(1, sizeof(mycss_stylesheet_t)); }