Program Listing for File cmb_process.h

Return to documentation for file (include/cmb_process.h)

/*
 * Copyright (c) Asbjørn M. Bonvik 2025-26.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef CIMBA_CMB_PROCESS_H
#define CIMBA_CMB_PROCESS_H

#include "cmb_assert.h"
#include "cmb_event.h"

#include "cmi_coroutine.h"
#include "cmi_slist.h"

#define CMB_PROCESS_NAMEBUF_SZ 32

#define CMB_PROCESS_SUCCESS INT64_C(0)

#define CMB_PROCESS_PREEMPTED INT64_C(-1)

#define CMB_PROCESS_INTERRUPTED INT64_C(-2)

#define CMB_PROCESS_STOPPED INT64_C(-3)

#define CMB_PROCESS_CANCELLED INT64_C(-4)

#define CMB_PROCESS_TIMEOUT INT64_C(-5)

enum cmb_process_state {
    CMB_PROCESS_CREATED = 0,
    CMB_PROCESS_RUNNING,
    CMB_PROCESS_FINISHED
};

struct cmb_process {
    struct cmi_coroutine core;
    int64_t priority;
    struct cmi_slist_head awaits;
    struct cmi_slist_head resources;
    struct cmi_slist_head waiters;
    char name[CMB_PROCESS_NAMEBUF_SZ];
};

typedef void *(cmb_process_func)(struct cmb_process *cp, void *context);

extern struct cmb_process *cmb_process_create(void);

extern void cmb_process_initialize(struct cmb_process *pp,
                                   const char *name,
                                   cmb_process_func procfunc,
                                   void *context,
                                   int64_t priority);

extern void cmb_process_terminate(struct cmb_process *pp);

extern void cmb_process_destroy(struct cmb_process *pp);

extern void cmb_process_start(struct cmb_process *pp);

[[maybe_unused]]
static inline struct cmb_process *cmb_process_current(void)
{
    const struct cmi_coroutine *cp = cmi_coroutine_current();
    const struct cmi_coroutine *mp = cmi_coroutine_main();

    return (cp == mp) ? NULL : (struct cmb_process *)cp;
}

[[maybe_unused]]
static inline int64_t cmb_process_yield(void)
{
    const struct cmb_process *pp = (struct cmb_process *)cmi_coroutine_current();
    cmb_assert_release(pp != (struct cmb_process *)cmi_coroutine_main());

    const int64_t sig = (int64_t)cmi_coroutine_yield(NULL);

    return sig;
}

extern void cmb_process_resume(struct cmb_process *pp, int64_t sig);

extern void cmb_process_timers_clear(struct cmb_process *pp);

extern uint64_t cmb_process_timer_add(struct cmb_process *pp, double dur, int64_t sig);

[[maybe_unused]]
static inline uint64_t cmb_process_timer_set(struct cmb_process *pp, const double dur, const int64_t sig)
{
    cmb_assert_release(pp != NULL);
    cmb_assert_release(dur >= 0.0);

    cmb_process_timers_clear(pp);
    const uint64_t handle = cmb_process_timer_add(pp, dur, sig);

    return handle;
}

extern bool cmb_process_timer_cancel(struct cmb_process *pp, uint64_t handle);

extern int64_t cmb_process_hold(double dur);

extern int64_t cmb_process_wait_process(struct cmb_process *awaited);

extern int64_t cmb_process_wait_event(uint64_t ev_handle);

extern void cmb_process_exit(void *retval);

extern void cmb_process_interrupt(struct cmb_process *pp,
                                  int64_t sig,
                                  int64_t pri);

extern int64_t cmb_process_stop(struct cmb_process *tgt, void *retval);

[[maybe_unused]]
static inline int64_t cmb_process_kill(struct cmb_process *tgt, void *retval)
{
    return cmb_process_stop(tgt, retval);
}

[[maybe_unused]]
static inline const char *cmb_process_name(const struct cmb_process *pp)
{
    cmb_assert_release(pp != NULL);

    return pp->name;
}

extern void cmb_process_name_set(struct cmb_process *pp,
                                 const char *name);

[[maybe_unused]]
static inline void *cmb_process_context(const struct cmb_process *pp)
{
    cmb_assert_release(pp != NULL);

    return cmi_coroutine_context((struct cmi_coroutine *)pp);
}

[[maybe_unused]]
static inline int64_t cmb_process_priority(const struct cmb_process *pp)
{
    cmb_assert_release(pp != NULL);

    return pp->priority;
}

extern void cmb_process_priority_set(struct cmb_process *pp, int64_t pri);

[[maybe_unused]]
static inline enum cmb_process_state cmb_process_status(const struct cmb_process *pp)
{
    cmb_assert_release(pp != NULL);

    const struct cmi_coroutine *cp = (struct cmi_coroutine *)pp;

    return (enum cmb_process_state)(cp->status);
}

extern void *cmb_process_exit_value(const struct cmb_process *pp);

#endif /* CIMBA_CMB_PROCESS_H */