Skip to content

Commit

Permalink
Update docs of changes, change thread_local setup
Browse files Browse the repository at this point in the history
- start the replacement of `thread_local` with macro `thrd_local` this macro will do emulation if feature not available in compiler or can be force to emulate if necessary. The macro create functions based off variable name.
  • Loading branch information
TheTechsTech committed Jul 3, 2024
1 parent 702fd17 commit 1d29a76
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 31 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ To be clear, this is a programming paradigm on structuring your code. Which can
You can read [Fibers, Oh My!](https://graphitemaster.github.io/fibers/) for a breakdown on how the actual context switch here is achieved by assembly. This library incorporates [libuv](http://docs.libuv.org) in a way that make providing callbacks unnecessary, same as in [Using C++ Resumable Functions with Libuv](https://devblogs.microsoft.com/cppblog/using-ibuv-with-c-resumable-functions/). **Libuv** is handling any hardware or multi-threading CPU access. This not necessary for library usage, the setup can be replaced with some other Event Loop library, or just disabled. There is a unmaintained [libasync](https://github.com/btrask/libasync) package tried combining **libco**, with **libuv** too, Linux only.

Two videos covering things to keep in mind about concurrency, [Building Scalable Deployments with Multiple Goroutines](https://www.youtube.com/watch?v=LNNaxHYFhw8) and [Detecting and Fixing Unbound Concurrency Problems](https://www.youtube.com/watch?v=gggi4GIvgrg).

## Table of Contents

* [Introduction](#introduction)
Expand Down Expand Up @@ -55,9 +53,13 @@ All internal functions that needs memory allocation is using these routines.
There will be at least one coroutine always present, the initial, required `co_main()`.
When a coroutine finish execution either by returning or exceptions, memory is released/freed.

> Note: This _resources management system_ outlined above has been _decoupled_ to _external libraries_ and now brought in as _dependencies_. Where the above is just wrapper calls to: [c-raii](https://github.com/zelang-dev/c-raii) for complete **Defer**, plus **C++ RAII** behavior, with an custom **malloc** replacement [rpmalloc](https://github.com/zelang-dev/rpmalloc), and emulated **C11 Threads and thread Pool** [cthread](https://github.com/zelang-dev/cthread).
- As such, the listed external libraries allow _smart auto memory management_ behaviors in any application, or any other **coroutine** library for that matter.

The other problem with **C** is the low level usage view. I initially started out with the concept of creating ***Yet Another Programming language***.
But after discovering [Cello High Level C](https://libcello.org/), and the general issues and need to still integrate with exiting C libraries.
This repo is now staging area the missing **C** runtime, [ZeLang](https://docs.zelang.dev). The documentation **WIP**.

But after discovering [Cello High Level C](https://libcello.org/), realizing the general issues and need to still integrate with exiting C libraries. This repo is now the staging area for the missing **C** runtime, [ZeLang](https://docs.zelang.dev). The documentation **WIP**, and source code hasn't been updated to recent changes in this library.

This **page**, `coroutine.h` and _examples folder_ files is the only current docs, but basic usage should be apparent.
The _coroutine execution_ part here is _completed_, but how it operates/behaves with other system resources is what still being developed and tested.
Expand Down
10 changes: 6 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ To be clear, this is a programming paradigm on structuring your code. Which can
You can read [Fibers, Oh My!](https://graphitemaster.github.io/fibers/) for a breakdown on how the actual context switch here is achieved by assembly. This library incorporates [libuv](http://docs.libuv.org) in a way that make providing callbacks unnecessary, same as in [Using C++ Resumable Functions with Libuv](https://devblogs.microsoft.com/cppblog/using-ibuv-with-c-resumable-functions/). **Libuv** is handling any hardware or multi-threading CPU access. This not necessary for library usage, the setup can be replaced with some other Event Loop library, or just disabled. There is a unmaintained [libasync](https://github.com/btrask/libasync) package tried combining **libco**, with **libuv** too, Linux only.

Two videos covering things to keep in mind about concurrency, [Building Scalable Deployments with Multiple Goroutines](https://www.youtube.com/watch?v=LNNaxHYFhw8) and [Detecting and Fixing Unbound Concurrency Problems](https://www.youtube.com/watch?v=gggi4GIvgrg).

## Table of Contents

* [Introduction](#introduction)
Expand Down Expand Up @@ -55,9 +53,13 @@ All internal functions that needs memory allocation is using these routines.
There will be at least one coroutine always present, the initial, required `co_main()`.
When a coroutine finish execution either by returning or exceptions, memory is released/freed.

> Note: This _resources management system_ outlined above has been _decoupled_ to _external libraries_ and now brought in as _dependencies_. Where the above is just wrapper calls to: [c-raii](https://github.com/zelang-dev/c-raii) for complete **Defer**, plus **C++ RAII** behavior, with an custom **malloc** replacement [rpmalloc](https://github.com/zelang-dev/rpmalloc), and emulated **C11 Threads and thread Pool** [cthread](https://github.com/zelang-dev/cthread).
- As such, the listed external libraries allow _smart auto memory management_ behaviors in any application, or any other **coroutine** library for that matter.

The other problem with **C** is the low level usage view. I initially started out with the concept of creating ***Yet Another Programming language***.
But after discovering [Cello High Level C](https://libcello.org/), and the general issues and need to still integrate with exiting C libraries.
This repo is now staging area the missing **C** runtime, [ZeLang](https://docs.zelang.dev). The documentation **WIP**.

But after discovering [Cello High Level C](https://libcello.org/), realizing the general issues and need to still integrate with exiting C libraries. This repo is now the staging area for the missing **C** runtime, [ZeLang](https://docs.zelang.dev). The documentation **WIP**, and source code hasn't been updated to recent changes in this library.

This **page**, `coroutine.h` and _examples folder_ files is the only current docs, but basic usage should be apparent.
The _coroutine execution_ part here is _completed_, but how it operates/behaves with other system resources is what still being developed and tested.
Expand Down
20 changes: 13 additions & 7 deletions include/coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#endif

#define time_Second 1000
#define time_Minute 60000
#define time_Hour 3600000

#include "uv_routine.h"
#include "raii.h"
Expand Down Expand Up @@ -740,6 +742,17 @@ C_API void coroutine_dec_count(void);
C_API void coroutine_log_reset(void);
C_API uv_args_t *coroutine_event_args(void);

/* Collect coroutines with references preventing immediate cleanup. */
C_API void gc_coroutine(routine_t *);

/* Collect channels with references preventing immediate cleanup. */
C_API void gc_channel(channel_t *);

C_API gc_channel_t *gc_channel_list(void);
C_API gc_coroutine_t *gc_coroutine_list(void);
C_API void gc_coroutine_free(void);
C_API void gc_channel_free(void);

C_API void channel_print(channel_t *);
C_API channel_t *channel_create(int, int);
C_API void channel_free(channel_t *);
Expand Down Expand Up @@ -889,13 +902,6 @@ C_API string_t co_itoa(int64_t number);
C_API int co_strpos(string_t text, string pattern);
C_API void co_strcpy(string dest, string_t src, size_t len);

C_API void gc_coroutine(routine_t *);
C_API void gc_channel(channel_t *);
C_API gc_channel_t *gc_channel_list(void);
C_API gc_coroutine_t *gc_coroutine_list(void);
C_API void gc_coroutine_free(void);
C_API void gc_channel_free(void);

/* Check if validated by json type */
C_API bool is_json(json_t *);

Expand Down
18 changes: 9 additions & 9 deletions src/channel.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
#include "coroutine.h"

static thread_local int channel_id_generate = 0;
static thread_local gc_channel_t *channel_list = NULL;
thrd_local_static(gc_channel_t *, channel_list, NULL)
static char error_message[ERROR_SCRAPE_SIZE] = {0};

void gc_channel(channel_t *ch) {
if (!channel_list)
channel_list = ht_channel_init();
if (is_channel_list_empty())
channel_list_update(ht_channel_init());

if (is_type(ch, CO_CHANNEL))
hash_put(channel_list, co_itoa(ch->id), ch);
hash_put(channel_list(), co_itoa(ch->id), ch);
}

CO_FORCE_INLINE gc_channel_t *gc_channel_list(void) {
return channel_list;
void gc_channel_free(void) {
if (!is_channel_list_empty())
hash_free(channel_list());
}

void gc_channel_free(void) {
if (channel_list)
hash_free(channel_list);
CO_FORCE_INLINE gc_channel_t *gc_channel_list(void) {
return channel_list();
}

channel_t *channel_create(int elem_size, int bufsize) {
Expand Down
14 changes: 7 additions & 7 deletions src/coroutine.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include "coroutine.h"

static thread_local gc_coroutine_t *coroutine_list = NULL;
thrd_local_static(gc_coroutine_t *, coroutine_list, NULL)

void gc_coroutine(routine_t *co) {
if (!coroutine_list)
coroutine_list = (gc_coroutine_t *)ht_group_init();
if (is_coroutine_list_empty())
coroutine_list_update(ht_group_init());

if (co->magic_number == CO_MAGIC_NUMBER)
hash_put(coroutine_list, co_itoa(co->cid), co);
hash_put(coroutine_list(), co_itoa(co->cid), co);
}

void gc_coroutine_free() {
if (coroutine_list)
hash_free(coroutine_list);
if (!is_coroutine_list_empty())
hash_free(coroutine_list());
}

CO_FORCE_INLINE gc_coroutine_t *gc_coroutine_list() {
return coroutine_list;
return coroutine_list();
}

values_type args_get(void_t params, int item) {
Expand Down

0 comments on commit 1d29a76

Please sign in to comment.