From c7378287dc3cc131bfbb7672a67adebb49e10d28 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 13 Jun 2025 17:03:56 +0900 Subject: [PATCH] fixed a wrong field name in chan.c that caused a segfault --- Makefile | 2 +- chan.c | 64 ++++++++++++++--------- ctx.c | 151 +++++++++++++++++++++++++++++++++---------------------- hip.h | 2 +- 4 files changed, 131 insertions(+), 88 deletions(-) diff --git a/Makefile b/Makefile index dc949e9..76844ec 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SRCS = chan.c ctx.c OBJS = $(SRCS:.c=.o) -CFLAGS := -Wall -g +CFLAGS := -Wall -g -O3 LDFLAGS := LIBS := -lrt diff --git a/chan.c b/chan.c index a297dd6..2d11fca 100644 --- a/chan.c +++ b/chan.c @@ -50,10 +50,12 @@ void hip_chan_close(hip_chan_t* c) int hip_chan_send(hip_chan_t* c, const void* ptr, hip_oow_t len) { - hip_uctx_t* self; + hip_t* hip; + hip_uctx_t* caller; int ret; - self = UCTX_FROM_LINK(c->hip->running); + hip = c->hip; + caller = UCTX_FROM_LINK(hip->running); // TODO: IS BUFFER EMPTY @@ -62,38 +64,41 @@ int hip_chan_send(hip_chan_t* c, const void* ptr, hip_oow_t len) hip_uctx_link_t* x; hip_uctx_t* xx; - /* remove the receiving routine from the queue and make it runnable */ x = HIP_LIST_HEAD(&c->recvq); - HIP_LIST_UNCHAIN(x); - HIP_LIST_ADD_BACK(x, &c->hip->runnables); xx = UCTX_FROM_LINK(x); - if (len > xx->chan_data_len) len = xx->chan_data_len; memcpy(xx->chan_data_ptr, ptr, len); +//printf ("USE SEND CHAT CALLER %p RECEIVER %p RET %p\n", caller, xx, xx->chan_ret_ptr); *(xx->chan_ret_ptr) = len; /* manipulate the return value of the receiver */ - hip_yield(c->hip); /* let other routines go first */ + /* remove the receiving routine from the queue and make it runnable */ + HIP_LIST_UNCHAIN(x); + HIP_LIST_ADD_BACK(x, &hip->runnables); + hip_yield(hip); /* let other routines go first */ return len; } /* remember the data holder and places the current running routine in the send queue */ - self->chan_data_ptr = (hip_uint8_t*)ptr; - self->chan_data_len = len; - self->chan_ret_ptr = &ret; /* remember the pointer to the return value holder to be set by the receiver */ - HIP_LIST_ADD_BACK(c->hip->running, &c->sendq); + caller->chan_data_ptr = (hip_uint8_t*)ptr; + caller->chan_data_len = len; + caller->chan_ret_ptr = &ret; /* remember the pointer to the return value holder to be set by the receiver */ +//printf ("REMEMBER SEND CHAT caller %p RET %p\n", caller, caller->chan_ret_ptr); - hip_switch(c->hip); + hip_switch(hip, &c->sendq); +//printf ("CALLER RETURNNING SEND caller %p, ret %p/%p => %d\n", caller, caller->chan_ret_ptr, &ret, ret); return ret; } int hip_chan_recv(hip_chan_t* c, void* ptr, hip_oow_t len) { - hip_uctx_t* self; + hip_t* hip; + hip_uctx_t* caller; int ret; - self = UCTX_FROM_LINK(c->hip->running); + hip = c->hip; + caller = UCTX_FROM_LINK(hip->running); /* TODO: IS THERE DATA IN BUFFER ? */ @@ -104,26 +109,35 @@ int hip_chan_recv(hip_chan_t* c, void* ptr, hip_oow_t len) /* remove the sending routine from the queue and make it runnable */ x = HIP_LIST_HEAD(&c->sendq); - HIP_LIST_UNCHAIN(x); - HIP_LIST_ADD_BACK(x, &c->hip->runnables); - - xx = UCTX_FROM_LINK(x); /* copy the data from the sending routine's buffer */ + xx = UCTX_FROM_LINK(x); if (len > xx->chan_data_len) len = xx->chan_data_len; /* TODO: do something else instead of simple truncation */ memcpy(ptr, xx->chan_data_ptr, len); - *(xx->chan_data_ptr) = len; /* manipulate the return value of the sender */ +//printf ("USE RECV CHAT caller %p sender %p RET %p\n",caller, xx, xx->chan_ret_ptr); + *(xx->chan_ret_ptr) = len; /* manipulate the return value of the sender */ - hip_yield(c->hip); /* let other routines go first */ + HIP_LIST_UNCHAIN(x); + HIP_LIST_ADD_BACK(x, &hip->runnables); + hip_yield(hip); /* let other routines go first */ return len; } /* remember the data holder and place the calling routine in the receive queue */ - self->chan_data_ptr = ptr; - self->chan_data_len = len; - self->chan_ret_ptr = &ret; /* remember the pointer to the return value holder to be set by the sender */ - HIP_LIST_ADD_BACK(c->hip->running, &c->recvq); + caller->chan_data_ptr = ptr; + caller->chan_data_len = len; + caller->chan_ret_ptr = &ret; /* remember the pointer to the return value holder to be set by the sender */ +//printf ("REMEMBER RECV caller %p CHAT RET %p\n", caller, caller->chan_ret_ptr); - hip_switch(c->hip); /* switch to the scheduler */ + hip_switch(hip, &c->recvq); /* switch to the scheduler */ +//printf ("CALLER RETURNNING RECV caller %p, ret %p/%p => %d\n", caller, caller->chan_ret_ptr, &ret, ret); return ret; } + +#if 0 +int hip_chan_select(hip_chan_t* chans, hip_oow_t count, int nonblock) +{ + /* returns the index to the chan that has data to read */ + return -1; +} +#endif diff --git a/ctx.c b/ctx.c index 06af4b9..ce5da4d 100644 --- a/ctx.c +++ b/ctx.c @@ -36,12 +36,13 @@ static void invoke_uf(unsigned int a, unsigned int b) #else uctx = (hip_uctx_t*)(((hip_oow_t)a << 32) | (hip_oow_t)b); #endif +printf ("invoke_uf START ...%p\n", uctx); uctx->uf(uctx, uctx->ctx); -printf ("invoke_uf XXXXXXXXXXXXXXXXXXXXX...%p\n", uctx); +printf ("invoke_uf DONE ...%p\n", uctx); //TODO: This part must not be interrupted by the timer handler??? hip = uctx->hip; - if (uctx == hip->uctx_sched) /* if not the scheduler itself */ + if (uctx == hip->uctx_sched) /* if not the scheduler itcaller */ { /* back to where the schedule got activated for the first time */ setcontext(&hip->uc_main); @@ -58,13 +59,14 @@ printf ("invoke_uf XXXXXXXXXXXXXXXXXXXXX...%p\n", uctx); if (uctx->flags & HIP_RTN_FLAG_AUTO_DESTROY) { +//printf (">>>>>>>>>> *********************** AUTHO DESTROYING UCTX %p\n", uctx); hip_uctx_close(uctx); -printf (">>>>>>>>>> *********************** CLOSED TERMINATED\n"); +//printf (">>>>>>>>>> *********************** CLOSED TERMINATED %p\n", uctx); } else { HIP_LIST_ADD_BACK(&uctx->uctx, &hip->terminated); -printf (">>>>>>>>>> ************************ ADDED TO TERMINATED\n"); +//printf (">>>>>>>>>> ************************ ADDED TO TERMINATED\n"); } setcontext(&hip->uctx_sched->uc); /* switch to the scheduler */ @@ -78,50 +80,53 @@ printf (">>>>>>>>>> ************************ ADDED TO TERMINATED\n"); hip_uctx_t* hip_uctx_open(hip_t* hip, hip_oow_t stack_size, int flags, hip_ufun_t uf, void* ctx) { - hip_uctx_t* uc; + hip_uctx_t* uctx; void* sp; - uc = (hip_uctx_t*)malloc(HIP_SIZEOF(*uc) + stack_size); - if (!uc) return HIP_NULL; - sp = (void*)(uc + 1); + uctx = (hip_uctx_t*)malloc(HIP_SIZEOF(*uctx) + stack_size); + if (HIP_UNLIKELY(!uctx)) return HIP_NULL; +printf ("MALLOC UCTX %p\n", uctx); - memset(uc, 0, HIP_SIZEOF(*uc) + stack_size); - uc->hip = hip; - uc->flags = flags; - uc->uf = uf; - uc->ctx = ctx; - uc->waiting_fd = HIP_INVALID_FD; + sp = (void*)(uctx + 1); - getcontext(&uc->uc); + memset(uctx, 0, HIP_SIZEOF(*uctx) + stack_size); + uctx->hip = hip; + uctx->flags = flags; + uctx->uf = uf; + uctx->ctx = ctx; + uctx->waiting_fd = HIP_INVALID_FD; + + getcontext(&uctx->uc); if (uf) { - sigemptyset (&uc->uc.uc_sigmask); -// sigaddset (&uc->uc.uc_sigmask, SIGRTMIN); /* block SIGRTMIN. TODO: take this value from the outer scheduler object? */ + sigemptyset (&uctx->uc.uc_sigmask); +// sigaddset (&uctx->uc.uc_sigmask, SIGRTMIN); /* block SIGRTMIN. TODO: take this value from the outer scheduler object? */ - uc->stid = VALGRIND_STACK_REGISTER(sp, (hip_uint8_t*)sp + stack_size); - uc->uc.uc_stack.ss_sp = sp; - uc->uc.uc_stack.ss_size = stack_size; - uc->uc.uc_stack.ss_flags = 0; - uc->uc.uc_link = HIP_NULL; + uctx->stid = VALGRIND_STACK_REGISTER(sp, (hip_uint8_t*)sp + stack_size); + uctx->uc.uc_stack.ss_sp = sp; + uctx->uc.uc_stack.ss_size = stack_size; + uctx->uc.uc_stack.ss_flags = 0; + uctx->uc.uc_link = HIP_NULL; #if (MKCTX_NARGS <= 1) - makecontext(&uc->uc, (void(*)(void))invoke_uf, 1, uc); + makecontext(&uctx->uc, (void(*)(void))invoke_uf, 1, uctx); #else - makecontext(&uc->uc, (void(*)(void))invoke_uf, 2, (unsigned int)((hip_oow_t)uc >> 32), (unsigned int)((hip_oow_t)uc & 0xFFFFFFFFu)); + makecontext(&uctx->uc, (void(*)(void))invoke_uf, 2, (unsigned int)((hip_oow_t)uctx >> 32), (unsigned int)((hip_oow_t)uctx & 0xFFFFFFFFu)); #endif } -printf("NEW UCTX %p\n", uc); - return uc; +printf("NEW UCTX %p\n", uctx); + return uctx; } void hip_uctx_close(hip_uctx_t* uctx) { - if (uctx->uf) - { - VALGRIND_STACK_DEREGISTER(uctx->stid); - } +//printf ("HIP_UCTX_CLOSE %p\n", uctx); + if (uctx->uf) VALGRIND_STACK_DEREGISTER(uctx->stid); + +//printf("FREEING UCTX %p\n", uctx); free(uctx); +//printf("FREEED UCTX %p\n", uctx); } void hip_uctx_swap(hip_uctx_t* uc, hip_uctx_t* new_uc) @@ -318,11 +323,12 @@ hip_t* hip_open(int flags) hip = (hip_t*)malloc(HIP_SIZEOF(*hip)); if (!hip) return HIP_NULL; +printf ("MALLOC HIP %p\n", hip); memset(hip, 0, HIP_SIZEOF(*hip)); hip->flags = flags; - /* initialize to an empty list by making each pointer point to itself.*/ + /* initialize to an empty list by making each pointer point to itcaller.*/ HIP_LIST_INIT(&hip->runnables); HIP_LIST_INIT(&hip->terminated); HIP_LIST_INIT(&hip->sleeping); @@ -364,6 +370,7 @@ hip_t* hip_open(int flags) if (hip->mux_id <= -1) { timer_delete(tid); +printf("FREEING HIP %p\n", hip); free(hip); return HIP_NULL; } @@ -434,6 +441,7 @@ void hip_close(hip_t* hip) if (hip->uctx_mux) hip_uctx_close(hip->uctx_mux); if (hip->uctx_sched) hip_uctx_close(hip->uctx_sched); +printf("FREEING HIP2 %p\n", hip); free(hip); } @@ -441,7 +449,7 @@ hip_uctx_t* hip_newrtn(hip_t* hip, int flags, hip_ufun_t uf, void* ctx) { hip_uctx_t* uctx; - uctx = hip_uctx_open(hip, 8192, flags, uf, ctx); /* TODO: stack size */ + uctx = hip_uctx_open(hip, 65535, flags, uf, ctx); /* TODO: stack size */ if (!uctx) return HIP_NULL; /* append to the list */ @@ -493,28 +501,48 @@ int hip_schedule(hip_t* hip, int preempt) return 0; } -void hip_yield(hip_t* hip) + +void hip_switch(hip_t* hip, hip_uctx_link_t* list_to_deposit) { - hip_uctx_t* rr; + hip_uctx_t* caller; assert (hip->running != HIP_NULL); /* switch from the running context to the scheduler context */ - HIP_LIST_ADD_BACK(hip->running, &hip->runnables); - rr = UCTX_FROM_LINK(hip->running); + HIP_LIST_ADD_BACK(hip->running, list_to_deposit); + caller = UCTX_FROM_LINK(hip->running); /* TODO: extract these lines to a macro or something */ -rr->cso++; +caller->cso++; hip->uctx_sched->csi++; - swapcontext(&rr->uc, &hip->uctx_sched->uc); + swapcontext(&caller->uc, &hip->uctx_sched->uc); } +void hip_yield(hip_t* hip) +{ + hip_switch(hip, &hip->runnables); +#if 0 + hip_uctx_t* caller; + /* the caller must deal with hip->running before calling this function */ + caller = UCTX_FROM_LINK(hip->running); + hip->running = HIP_NULL; + swapcontext(&caller->uc, &hip->uctx_sched->uc); /* switch to the scheduler */ +#endif +} + +void hip_suspend(hip_t* hip) +{ + /* TODO: this isn't needed as of now. delete it if it's not really needed eventually */ + hip_switch(hip, &hip->suspended); +} + + void hip_sleep(hip_t* hip, hip_nsecdur_t nsecs) { - hip_uctx_t* rr; + hip_uctx_t* caller; assert (hip->running != HIP_NULL); - rr = UCTX_FROM_LINK(hip->running); - rr->wakeup_time = monotime() + nsecs; + caller = UCTX_FROM_LINK(hip->running); + caller->wakeup_time = monotime() + nsecs; /* TODO: switch to HEAP. for now simply linear search to keep this list sorted. */ if (!HIP_LIST_IS_EMPTY(&hip->sleeping)) @@ -524,7 +552,7 @@ void hip_sleep(hip_t* hip, hip_nsecdur_t nsecs) for (l = HIP_LIST_HEAD(&hip->sleeping); l != &hip->sleeping; l = l->next) { r = UCTX_FROM_LINK(l); - if (rr->wakeup_time <= r->wakeup_time) + if (caller->wakeup_time <= r->wakeup_time) { HIP_LIST_CHAIN(hip->running, l->prev, l); goto do_sched; @@ -536,22 +564,7 @@ void hip_sleep(hip_t* hip, hip_nsecdur_t nsecs) do_sched: hip->running = HIP_NULL; - swapcontext(&rr->uc, &hip->uctx_sched->uc); /* switch to the scheduler */ -} - -void hip_suspend(hip_t* hip) -{ - HIP_LIST_ADD_BACK(hip->running, &hip->suspended); - hip_switch(hip); -} - -void hip_switch(hip_t* hip) -{ - hip_uctx_t* rr; - /* the caller must deal with hip->running before calling this function */ - rr = UCTX_FROM_LINK(hip->running); - hip->running = HIP_NULL; - swapcontext(&rr->uc, &hip->uctx_sched->uc); /* switch to the scheduler */ + swapcontext(&caller->uc, &hip->uctx_sched->uc); /* switch to the scheduler */ } void hip_awaitio(hip_t* hip, int fd, int flags) @@ -712,7 +725,6 @@ static void uf1(hip_uctx_t* uc, void* ctx) { hip_chan_t* chan; int i; - char buf[32]; chan = (hip_chan_t*)ctx; @@ -726,9 +738,15 @@ printf (">> UF1 SEC [%d]\n", i); hip_sleep(uc->hip, 1000000000); } + { + int n; + char buf[32]; printf (">> UF1 ALMOST DONE. WAITING FOR UF3\n"); - i = hip_chan_recv(chan, buf, sizeof(buf)); + n = hip_chan_recv(chan, buf, sizeof(buf)); printf (">> UF1 RECEIVED [%.*s]\n", (int)i, buf); + n = hip_chan_send(chan, "holy cow", 8); + printf (">> UF1 SENT [%d]\n", (int)n); + } } static void uf2(hip_uctx_t* uc, void* ctx) @@ -756,6 +774,7 @@ static void uf3(hip_uctx_t* uc, void* ctx) hip = uc->hip; chan = (hip_chan_t*)ctx; +#if 0 memset(&sa, 0, HIP_SIZEOF(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr("142.250.206.196"); @@ -784,6 +803,7 @@ printf ("*********CONNECTED>>>>>>>>>>>>>>>\n"); } socket_close(hip, fd); printf ("*********DISCONNECTED>>>>>>>>>>>>>>>\n"); +#endif for (i = 0; i < 15; i++) { @@ -796,7 +816,15 @@ hip_sleep(uc->hip, 1000000000); if (i == 8) hip_newrtn(uc->hip, HIP_RTN_FLAG_AUTO_DESTROY, uf2, HIP_NULL); } printf (">> UF3 DONE DONE\n"); - hip_chan_send(chan, "hello", 5); + + { + int n; + char buf[64]; + n = hip_chan_send(chan, "hello", 5); +printf (">> UF3 SENT %d\n", (int)n); + n = hip_chan_recv(chan, buf, sizeof(buf)); +printf (">> UF3 RECV [%.*s]\n", (int)n, buf); + } } int main() @@ -804,6 +832,7 @@ int main() hip_t* hip; hip_chan_t* chan; +setbuf(stdout, NULL); hip = hip_open(HIP_FLAG_LAZY); chan = hip_chan_open(hip, 100); diff --git a/hip.h b/hip.h index f12558a..f55b648 100644 --- a/hip.h +++ b/hip.h @@ -114,7 +114,7 @@ void hip_uctx_close(hip_uctx_t* uctx); void hip_yield(hip_t* hip); void hip_sleep(hip_t* hip, hip_nsecdur_t nsecs); -void hip_switch(hip_t* hip); +void hip_switch(hip_t* hip, hip_uctx_link_t* list_to_deposit); void hip_suspend(hip_t* hip);