18 Commits
Author SHA1 Message Date
tidwall 9e8e19e4bc Allow all tests to run before fail
Vanilla C CI / build (push) Has been cancelled
2024-07-25 19:34:58 -07:00
tidwall a15af5b486 Ensure clang llvm versions align 2024-07-25 19:24:15 -07:00
tidwall 5a22d6f322 Update sco, support for cosmopolitan
This commit adds basic support for the Cosmopolitan libc, which
allows for portable executables.

https://github.com/jart/cosmopolitan

See #18
2024-07-25 08:12:27 -07:00
tidwall 86a9a26fde Update tests run script
Move user CFLAGS to be included at the end of the cc options.
Ensure zig-cc on Mac uses -O1 to workaround a quirk.
2024-07-25 06:52:30 -07:00
tidwall b53d0a29fe Add C++ support 2024-07-25 06:52:06 -07:00
tidwall 1bc011c83a Change opaque signatures for sync types
Removes the alignas keyword in favor of int64 and pointer types.
2024-07-25 06:49:37 -07:00
Josh 9967411f02 Explicitly define handler
This fixes a bug with zig-cc

See #20
2024-07-25 00:55:23 +00:00
tidwall 6827ebaf18 Update README
Remove metion of c11. See #17
2024-07-04 08:46:15 -07:00
tidwall 4788e0eef7 Fix typos in neco.h
From @yeh-sudo in #16
2024-06-25 06:08:19 -07:00
tidwall 43725ee34a Add port scanner example 2024-05-31 19:48:14 -07:00
tidwall 7d03e805d8 Align inner types too 2024-05-13 20:22:15 -07:00
tidwall 052e4c5e5d Fix worker test
Github actions were running low on memory causing ENOMEM errors
when running the test_work test.

This commit lowers the number of background coroutines in hopes
to alleviate the memory pressure.
2024-05-13 05:55:58 -07:00
tidwall d808a81cd9 Faster neco_start
This commit alters the behavior of neco_start in order to shorten
the time it takes to start a coroutine and switching back to the
parent coroutine. Making for faster neco_start.

See #12
2024-05-13 05:21:53 -07:00
tidwall 5f48ee01b6 Add gettid for emscripten 2024-05-11 18:13:51 -07:00
Josh Baker 3d4da9f841 Merge pull request #13 from deckarep/fix-opaque-type-alignment
fixes alignment on opaque types as discueed with @tidwall
2024-05-11 18:04:27 -07:00
Ralph Caraveo d829d94d8d fixes alignment on opaque types as discueed with @tidwall 2024-05-11 14:20:30 -07:00
tidwall d5d9d4fe82 Adjust neco_main specifiers to remove warnings
Remove the static inline specifier from the __neco_main signature
to avoid old-style-declaration warning when -Wextra is provided.
2024-04-24 19:57:20 -07:00
tidwall 2c3852d9e6 Update llco
See #9
See https://github.com/tidwall/llco/commit/b6a5a5b886e8a3e06806d741b84571c0b1e1f8d0
2024-04-19 19:41:30 -07:00
12 changed files with 176 additions and 100 deletions
+2
View File
@@ -14,3 +14,5 @@ tmp.*
*.testdata
*.sqlite3
*.db
*.elf
*.dbg
+1 -1
View File
@@ -48,7 +48,7 @@ concurrency models like async/await.
## Using
Just drop the "neco.c" and "neco.h" files into your project. Uses standard C11 so most modern C compilers should work.
Just drop the "neco.c" and "neco.h" files into your project. Most modern C compilers should work.
```sh
cc -c neco.c
+4 -2
View File
@@ -1,2 +1,4 @@
import github.com/tidwall/sco v0.1.0
import github.com/tidwall/stack v0.1.0
import github.com/tidwall/sco v0.2.1
sum 9610203b4ce6f6e3cac862a3deb99cb418acac7c sco.c
sum 92baa4119d14dbb2b1effcd2eaeb4adcba8befc1 sco.h
Vendored
+12 -7
View File
@@ -135,6 +135,11 @@ static void llco_exit(void) {
#error LLCO_ASM must not be defined
#endif
#if defined(__COSMOCC__) && !defined(LLCO_NOASM)
// Cosmopolitan has issues with asm code
#define LLCO_NOASM
#endif
// Passing the entry function into assembly requires casting the function
// pointer to an object pointer, which is forbidden in the ISO C spec but
// allowed in posix. Ignore the warning attributed to this requirement when
@@ -1169,7 +1174,7 @@ const char *llco_method(void *caps) {
}
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(_WIN32) && \
!defined(LLCO_NOUNWIND)
!defined(LLCO_NOUNWIND) && !defined(__COSMOCC__)
#include <unwind.h>
#include <string.h>
@@ -1182,7 +1187,7 @@ struct llco_dlinfo {
void *dli_saddr; /* Address of nearest symbol */
};
#ifdef __linux__
#if defined(__linux__) && !defined(_GNU_SOURCE)
int dladdr(const void *, void *);
#endif
@@ -1853,11 +1858,11 @@ static void sco_entry(void *udata) {
co->prev = co;
co->next = co;
if (sco_cur) {
// Reschedule the coroutine that started this one
sco_list_push_back(&sco_yielders, co);
sco_list_push_back(&sco_yielders, sco_cur);
sco_nyielders += 2;
sco_switch(false, false);
// Reschedule the coroutine that started this one immediately after
// all running coroutines, but before any yielding coroutines, and
// continue running the started coroutine.
sco_list_push_back(&sco_runners, sco_cur);
sco_nrunners++;
}
sco_cur = co;
if (sco_user_entry) {
+9
View File
@@ -12,6 +12,12 @@
#include <string.h>
#include <pthread.h>
#ifdef WORKER_STATIC
#define WORKER_API static
#else
#define WORKER_API
#endif
#define WORKER_DEF_TIMEOUT INT64_C(1000000000) // one second
#define WORKER_DEF_MAX_THREADS 2
#define WORKER_DEF_MAX_THREAD_ENTRIES 32
@@ -46,6 +52,7 @@ struct worker {
void (*free)(void*);
};
WORKER_API
void worker_free(struct worker *worker) {
if (worker) {
if (worker->threads) {
@@ -70,6 +77,7 @@ void worker_free(struct worker *worker) {
}
}
WORKER_API
struct worker *worker_new(struct worker_opts *opts) {
// Load options
int nthreads = opts ? opts->max_threads : 0;
@@ -164,6 +172,7 @@ static void *worker_entry(void *arg) {
/// @param udata any user data
/// @return true for success or false if no worker is available.
/// @return false for invalid arguments. Worker and work must no be null.
WORKER_API
bool worker_submit(struct worker *worker, int64_t pin, void(*work)(void *udata),
void *udata)
{
+48
View File
@@ -0,0 +1,48 @@
// Port scanning
//
// Thanks to @sigidagi for recommending this example.
// See https://github.com/tidwall/neco/issues/14
#include <stdio.h>
#include <unistd.h>
#include "../neco.h"
void co_dial_port(int argc, void** argv) {
const char *host = argv[0]; // host
int port = *(int*)argv[1]; // port
neco_waitgroup *wg = argv[2]; // waitgroup
// Dial the port with a one second deadline
char addr[256];
snprintf(addr, sizeof(addr), "%s:%d", host, port);
int fd = neco_dial_dl("tcp", addr, neco_now() + NECO_SECOND);
if (fd < 0) {
printf("%-5d FAIL\t%s\n", port, neco_strerror(neco_lasterr()));
} else {
printf("%-5d OK\n", port);
close(fd);
}
// Notify the waitgroup that we are done.
neco_waitgroup_done(wg);
}
int neco_main(int argc, char** argv) {
const char *host = "scanme.nmap.org";
int ports[] = { 22, 80, 8080, 443 };
// Use a waitgroup to synchronize the coroutines
neco_waitgroup wg;
neco_waitgroup_init(&wg);
// Dial all the ports
printf("%s\n", host);
for (int i = 0; i < sizeof(ports)/sizeof(int); i++) {
neco_waitgroup_add(&wg, 1);
neco_start(co_dial_port, 3, host, &ports[i], &wg);
}
// Wait for all coroutines to finish
neco_waitgroup_wait(&wg);
return 0;
}
+50 -21
View File
@@ -97,8 +97,15 @@ NECO_NOWRITEWORKERS // Disable all write workers
#undef NECO_BURST
#define NECO_BURST 1
#endif
#if NECO_MAXWORKERS > 8
#undef NECO_MAXWORKERS
#define NECO_MAXWORKERS 8
#endif
#if NECO_MAXRINGSIZE > 4
#undef NECO_MAXRINGSIZE
#define NECO_MAXRINGSIZE 4
#endif
#endif
// The following is only needed when LLCO_NOASM or LLCO_STACKJMP is defined.
// This same block is duplicated in the llco.c block below.
@@ -137,6 +144,7 @@ NECO_NOWRITEWORKERS // Disable all write workers
#define SCO_STATIC
#define STACK_STATIC
#define WORKER_STATIC
#if defined(__GNUC__)
#pragma GCC diagnostic push
@@ -281,6 +289,11 @@ static void llco_exit(void) {
#error LLCO_ASM must not be defined
#endif
#if defined(__COSMOCC__) && !defined(LLCO_NOASM)
// Cosmopolitan has issues with asm code
#define LLCO_NOASM
#endif
// Passing the entry function into assembly requires casting the function
// pointer to an object pointer, which is forbidden in the ISO C spec but
// allowed in posix. Ignore the warning attributed to this requirement when
@@ -1315,7 +1328,7 @@ const char *llco_method(void *caps) {
}
#if defined(__GNUC__) && !defined(__EMSCRIPTEN__) && !defined(_WIN32) && \
!defined(LLCO_NOUNWIND)
!defined(LLCO_NOUNWIND) && !defined(__COSMOCC__)
#include <unwind.h>
#include <string.h>
@@ -1328,7 +1341,7 @@ struct llco_dlinfo {
void *dli_saddr; /* Address of nearest symbol */
};
#ifdef __linux__
#if defined(__linux__) && !defined(_GNU_SOURCE)
int dladdr(const void *, void *);
#endif
@@ -1999,11 +2012,11 @@ static void sco_entry(void *udata) {
co->prev = co;
co->next = co;
if (sco_cur) {
// Reschedule the coroutine that started this one
sco_list_push_back(&sco_yielders, co);
sco_list_push_back(&sco_yielders, sco_cur);
sco_nyielders += 2;
sco_switch(false, false);
// Reschedule the coroutine that started this one immediately after
// all running coroutines, but before any yielding coroutines, and
// continue running the started coroutine.
sco_list_push_back(&sco_runners, sco_cur);
sco_nrunners++;
}
sco_cur = co;
if (sco_user_entry) {
@@ -2622,6 +2635,12 @@ void *stack_addr(struct stack *stack) {
#include <string.h>
#include <pthread.h>
#ifdef WORKER_STATIC
#define WORKER_API static
#else
#define WORKER_API
#endif
#define WORKER_DEF_TIMEOUT INT64_C(1000000000) // one second
#define WORKER_DEF_MAX_THREADS 2
#define WORKER_DEF_MAX_THREAD_ENTRIES 32
@@ -2656,6 +2675,7 @@ struct worker {
void (*free)(void*);
};
WORKER_API
void worker_free(struct worker *worker) {
if (worker) {
if (worker->threads) {
@@ -2680,6 +2700,7 @@ void worker_free(struct worker *worker) {
}
}
WORKER_API
struct worker *worker_new(struct worker_opts *opts) {
// Load options
int nthreads = opts ? opts->max_threads : 0;
@@ -2774,6 +2795,7 @@ static void *worker_entry(void *arg) {
/// @param udata any user data
/// @return true for success or false if no worker is available.
/// @return false for invalid arguments. Worker and work must no be null.
WORKER_API
bool worker_submit(struct worker *worker, int64_t pin, void(*work)(void *udata),
void *udata)
{
@@ -2856,7 +2878,7 @@ bool worker_submit(struct worker *worker, int64_t pin, void(*work)(void *udata),
#include <sys/epoll.h>
#include <sys/eventfd.h>
#define NECO_POLL_EPOLL
#elif defined(__EMSCRIPTEN__) || defined(_WIN32)
#elif defined(__EMSCRIPTEN__) || defined(_WIN32) || defined(__COSMOCC__)
// #warning Webassembly has no polling
#define NECO_POLL_DISABLED
#else
@@ -3235,7 +3257,7 @@ struct cleanup {
void (*routine)(void *);
void *arg;
struct cleanup *next;
} aligned16;
};
////////////////////////////////////////////////////////////////////////////////
// colist - The standard queue type that is just a doubly linked list storing
@@ -3247,7 +3269,7 @@ struct coroutine;
struct colink {
struct coroutine *prev;
struct coroutine *next;
} aligned16;
};
struct colist {
struct colink head;
@@ -3669,10 +3691,15 @@ static struct coroutine *evexists(int fd, enum evkind kind) {
static int is_main_thread(void) {
return IsGUIThread(false);
}
#elif defined(__linux__) || defined(__EMSCRIPTEN__)
#elif defined(__linux__)
static int is_main_thread(void) {
return getpid() == (pid_t)syscall(SYS_gettid);
}
#elif defined(__EMSCRIPTEN__) || defined(__COSMOCC__)
int gettid(void);
static int is_main_thread(void) {
return getpid() == gettid();
}
#else
int pthread_main_np(void);
static int is_main_thread(void) {
@@ -4351,7 +4378,6 @@ static int run(void(*coroutine)(int, void**), int nargs, va_list *args,
colist_init(&rt->iolist);
#endif
// Start the main coroutine. Actually, it's just queued to run first.
ret = start(coroutine, nargs, args, argv, 0, 0);
if (ret != NECO_OK) {
@@ -7055,13 +7081,13 @@ int neco_serve(const char *network, const char *address) {
struct neco_mutex {
int64_t rtid; // runtime id
bool locked; // mutex is locked (read or write)
int rlocked; // read lock counter
struct colist queue; // coroutine doubly linked list
int rlocked; // read lock counter
bool locked; // mutex is locked (read or write)
};
static_assert(sizeof(neco_mutex) >= sizeof(struct neco_mutex), "");
static_assert(_Alignof(neco_mutex) == _Alignof(struct neco_mutex), "");
static int mutex_init(neco_mutex *mutex) {
struct neco_mutex *mu = (void*)mutex;
@@ -7312,12 +7338,13 @@ int neco_mutex_destroy(neco_mutex *mutex) {
}
struct neco_waitgroup {
int64_t rtid;
int count;
struct colist queue;
int64_t rtid; // runtime id
struct colist queue; // coroutine doubly linked list
int count; // current wait count
};
static_assert(sizeof(neco_waitgroup) >= sizeof(struct neco_waitgroup), "");
static_assert(_Alignof(neco_waitgroup) == _Alignof(struct neco_waitgroup), "");
inline
static int check_waitgroup(struct neco_waitgroup *wg) {
@@ -7460,11 +7487,12 @@ int neco_waitgroup_destroy(neco_waitgroup *waitgroup) {
}
struct neco_cond {
int64_t rtid; // runtime id
struct colist queue; // coroutine doubly linked list
int64_t rtid; // runtime id
struct colist queue; // coroutine doubly linked list
};
static_assert(sizeof(neco_cond) >= sizeof(struct neco_cond), "");
static_assert(_Alignof(neco_cond) == _Alignof(struct neco_cond), "");
static int cond_init0(struct neco_cond *cv) {
memset(cv, 0, sizeof(struct neco_cond));
@@ -8685,6 +8713,7 @@ static void iowork(void *udata) {
#endif
static int workfn(int64_t pin, void(*work)(void *udata), void *udata) {
(void)pin;
struct coroutine *co = coself();
if (!work) {
return NECO_INVAL;
+20 -13
View File
@@ -19,6 +19,10 @@
#include <sys/socket.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
// basic operations
////////////////////////////////////////////////////////////////////////////////
@@ -97,7 +101,7 @@ int neco_gen_close(neco_gen *gen);
/// @}
////////////////////////////////////////////////////////////////////////////////
// synchonization mechanisms
// synchronization mechanisms
////////////////////////////////////////////////////////////////////////////////
/// @defgroup Mutexes Mutexes
@@ -106,7 +110,7 @@ int neco_gen_close(neco_gen *gen);
/// to a variable or set of variables and helps to avoid data inconsistencies
/// due to race conditions.
/// @{
typedef struct { char _[48]; } neco_mutex;
typedef struct { int64_t _0; intptr_t _1[5]; } neco_mutex;
#define NECO_MUTEX_INITIALIZER { 0 }
@@ -128,8 +132,7 @@ int neco_mutex_tryrdlock(neco_mutex *mutex);
/// At the same time, neco_waitgroup_wait() can be used to block until all
/// coroutines are completed.
/// @{
typedef struct { char _[48]; } neco_waitgroup;
typedef struct { int64_t _0; intptr_t _1[5]; } neco_waitgroup;
#define NECO_WAITGROUP_INITIALIZER { 0 }
int neco_waitgroup_init(neco_waitgroup *waitgroup);
@@ -143,7 +146,7 @@ int neco_waitgroup_wait_dl(neco_waitgroup *waitgroup, int64_t deadline);
/// A condition variable is a synchronization mechanism that allows coroutines
/// to suspend execution until some condition is true.
/// @{
typedef struct { char _[48]; } neco_cond;
typedef struct { int64_t _0; intptr_t _1[5]; } neco_cond;
#define NECO_COND_INITIALIZER { 0 }
int neco_cond_init(neco_cond *cond);
@@ -208,7 +211,7 @@ int neco_dial_dl(const char *network, const char *address, int64_t deadline);
/// @}
////////////////////////////////////////////////////////////////////////////////
// cancellation
// cancelation
////////////////////////////////////////////////////////////////////////////////
/// @defgroup Cancelation Cancelation
@@ -225,8 +228,9 @@ int neco_cancel_dl(int64_t id, int64_t deadline);
int neco_setcanceltype(int type, int *oldtype);
int neco_setcancelstate(int state, int *oldstate);
#define neco_cleanup_push(routine, arg) {__neco_c0(&(char[32]){0},routine,arg);
#define neco_cleanup_pop(execute) __neco_c1(execute);}
#define neco_cleanup_push(routine, arg) {char __neco_handler[32]={0};\
__neco_c0(__neco_handler,routine,arg);
#define neco_cleanup_pop(execute) __neco_c1(execute);}
/// @}
@@ -261,13 +265,12 @@ int neco_signal_unwatch(int signo);
/// @}
////////////////////////////////////////////////////////////////////////////////
// background worker
////////////////////////////////////////////////////////////////////////////////
/// @defgroup Worker Background worker
/// Run arbritary code in a background worker thread
/// Run arbitrary code in a background worker thread
/// @{
int neco_work(int64_t pin, void(*work)(void *udata), void *udata);
@@ -422,10 +425,10 @@ ssize_t neco_stream_buffered_write_size(neco_stream *stream);
#include <stdlib.h>
#define neco_main \
static inline __neco_main0(int argc, char *argv[]); \
__neco_main(int argc, char *argv[]); \
static void _neco_main(int argc, void *argv[]) { \
(void)argc; \
__neco_exit_prog(__neco_main0(*(int*)argv[0], *(char***)argv[1])); \
__neco_exit_prog(__neco_main(*(int*)argv[0], *(char***)argv[1])); \
} \
int main(int argc, char *argv[]) { \
neco_env_setpaniconerror(true); \
@@ -434,7 +437,7 @@ int main(int argc, char *argv[]) { \
fprintf(stderr, "neco_start: %s (code %d)\n", neco_strerror(ret), ret); \
return -1; \
}; \
int static inline __neco_main0
int __neco_main
////////////////////////////////////////////////////////////////////////////////
// private functions, not to be call directly
@@ -450,4 +453,8 @@ void __neco_exit_prog(int);
#define EAI_SYSTEM 11
#endif
#ifdef __cplusplus
}
#endif
#endif // NECO_H
+26 -13
View File
@@ -6,6 +6,7 @@ set -e
cd $(dirname "${BASH_SOURCE[0]}")
OK=0
FAILS=
finish() {
rm -fr *.o
rm -fr *.out
@@ -16,7 +17,7 @@ finish() {
rm -fr *.c.worker.js
rm -fr *.c.wasm
if [[ "$OK" != "1" ]]; then
echo "FAIL"
echo "FAIL [`echo "$FAILS" | xargs`]"
fi
}
trap finish EXIT
@@ -43,8 +44,10 @@ fi
if [[ "$CC" == "" ]]; then
CC=cc
fi
UCFLAGS=$CFLAGS
CFLAGS=
if [[ "$1" != "bench" ]]; then
CFLAGS="-O0 -g3 -Wall -Wextra -fstrict-aliasing $CFLAGS"
CFLAGS="-O0 -g2 -Wall -Wextra -fstrict-aliasing $CFLAGS"
CCVERSHEAD="$($CC --version | head -n 1)"
if [[ "$CCVERSHEAD" == "" ]]; then
exit 1
@@ -52,8 +55,10 @@ if [[ "$1" != "bench" ]]; then
if [[ "$CCVERSHEAD" == *"clang"* ]]; then
CLANGVERS="$(echo "$CCVERSHEAD" | awk '{print $4}' | awk -F'[ .]+' '{print $1}')"
INSTALLDIR="$($CC --version | grep InstalledDir)"
INSTALLDIR="${INSTALLDIR#* }"
fi
if [[ "$CC" == *"zig"* ]]; then
# echo Zig does not support asans
NOSANS=1
@@ -109,14 +114,15 @@ elif [[ "`uname`" == *"_NT-"* ]]; then
fi
if [[ "$CC" == *"zig"* ]]; then
# Without -O3, 'zig cc' has quirks issues on Mac OS.
CFLAGS="$CFLAGS -O3"
# Stack unwinding is not supported yet
# https://github.com/ziglang/zig/issues/9046
CFLAGS="$CFLAGS -DLLCO_NOUNWIND"
# Without -O1, 'zig cc' has quirks issues on Mac OS.
if [[ "`uname`" == "Darwin" ]]; then
CFLAGS="$CFLAGS -O1"
fi
fi
CFLAGS="$CFLAGS $UCFLAGS"
CC=${CC:-cc}
echo "CC: $CC"
@@ -205,6 +211,7 @@ else
if [[ "$WITHCOV" == "1" ]]; then
export LLVM_PROFILE_FILE="$f.profraw"
fi
set +e
if [[ "$VALGRIND" == "1" ]]; then
valgrind --leak-check=yes ./$f.test $@
elif [[ "$CC" == "emcc" ]]; then
@@ -212,24 +219,30 @@ else
else
./$f.test $@
fi
if [[ "$?" != "0" ]]; then
FAILS="$FAILS$(echo "$f" | cut -f 1 -d '.') "
fi
set -e
done
OK=1
echo "OK"
if [[ "$FAILS" == "" ]]; then
OK=1
echo "OK"
fi
if [[ "$COVREGIONS" == "" ]]; then
COVREGIONS="false"
fi
if [[ "$WITHCOV" == "1" ]]; then
$LLVM_PROFDATA merge *.profraw -o test.profdata
$LLVM_COV report *.test ../neco.c -ignore-filename-regex=.test. \
$INSTALLDIR/$LLVM_PROFDATA merge *.profraw -o test.profdata
$INSTALLDIR/$LLVM_COV report *.test ../neco.c -ignore-filename-regex=.test. \
-j=4 \
-show-functions=true \
-instr-profile=test.profdata > /tmp/test.cov.sum.txt
# echo coverage: $(cat /tmp/test.cov.sum.txt | grep TOTAL | awk '{ print $NF }')
echo covered: "$(cat /tmp/test.cov.sum.txt | grep TOTAL | awk '{ print $7; }') (lines)"
$LLVM_COV show *.test ../neco.c -ignore-filename-regex=.test. \
$INSTALLDIR/$LLVM_COV show *.test ../neco.c -ignore-filename-regex=.test. \
-j=4 \
-show-regions=true \
-show-expansions=$COVREGIONS \
+3 -3
View File
@@ -96,14 +96,14 @@ void co_sched1(int argc, void *argv[]) {
int *i = argv[1];
a[(*i)++] = 'B';
assert(neco_yield() == NECO_OK);
a[(*i)++] = 'D';
a[(*i)++] = 'F';
}
void co_sched2(int argc, void *argv[]) {
assert(argc == 2);
char *a = argv[0];
int *i = argv[1];
a[(*i)++] = 'E';
a[(*i)++] = 'D';
assert(neco_yield() == NECO_OK);
a[(*i)++] = 'G';
}
@@ -116,7 +116,7 @@ void co_sched(int argc, void *argv[]) {
assert(neco_start(co_sched1, 2, a, i) == NECO_OK);
a[(*i)++] = 'C';
assert(neco_start(co_sched2, 2, a, i) == NECO_OK);
a[(*i)++] = 'F';
a[(*i)++] = 'E';
assert(neco_yield() == NECO_OK);
a[(*i)++] = 'H';
}
-39
View File
@@ -343,30 +343,6 @@ void test_sync_cond_deadline(void) {
expect(neco_start(co_sync_cond_deadline, 0), NECO_OK);
}
void co_sync_mutex_rw_order_child2(int argc, void *argv[]) {
assert(argc == 2);
neco_mutex *mu = argv[0];
struct order *order = argv[1];
order_add(order, 17);
expect(neco_mutex_rdlock(mu), NECO_OK);
order_add(order, 23);
expect(neco_mutex_unlock(mu), NECO_OK);
order_add(order, 26);
}
void co_sync_mutex_rw_order_child3(int argc, void *argv[]) {
assert(argc == 2);
neco_mutex *mu = argv[0];
struct order *order = argv[1];
order_add(order, 19);
expect(neco_mutex_trylock(mu), NECO_BUSY);
order_add(order, 20);
expect(neco_mutex_rdlock(mu), NECO_OK);
order_add(order, 24);
expect(neco_mutex_unlock(mu), NECO_OK);
order_add(order, 27);
}
void co_sync_mutex_rw_order_child(int argc, void *argv[]) {
assert(argc == 2);
neco_mutex *mu = argv[0];
@@ -382,12 +358,6 @@ void co_sync_mutex_rw_order_child(int argc, void *argv[]) {
order_add(order, 13);
expect(neco_yield(), NECO_OK);
order_add(order, 14);
expect(neco_start(co_sync_mutex_rw_order_child2, 2, mu, order), NECO_OK);
order_add(order, 18);
expect(neco_start(co_sync_mutex_rw_order_child3, 2, mu, order), NECO_OK);
order_add(order, 21);
expect(neco_mutex_unlock(mu), NECO_OK);
order_add(order, 28);
}
void co_sync_mutex_rw_order(int argc, void *argv[]) {
@@ -414,15 +384,6 @@ void co_sync_mutex_rw_order(int argc, void *argv[]) {
order_add(&order, 12);
expect(neco_mutex_unlock(mu), NECO_OK);
order_add(&order, 15);
expect(neco_mutex_tryrdlock(mu), NECO_BUSY);
order_add(&order, 16);
expect(neco_mutex_rdlock(mu), NECO_OK);
order_add(&order, 22);
expect(neco_mutex_unlock(mu), NECO_OK);
order_add(&order, 25);
expect(neco_yield(), NECO_OK);
order_add(&order, 29);
expect(neco_mutex_destroy(mu), NECO_OK);
order_check(&order);
}
+1 -1
View File
@@ -15,7 +15,7 @@ void co_work_runner(int argc, void *argv[]) {
void co_work(int argc, void *argv[]) {
(void)argc; (void)argv;
for (int i = 0; i < 10000; i++) {
for (int i = 0; i < 100; i++) {
expect(neco_start(co_work_runner, 1, &i), NECO_OK);
}
}