{"id":15345690,"url":"https://github.com/git-hulk/libtask-annotation","last_synced_at":"2025-07-08T04:06:59.407Z","repository":{"id":75625324,"uuid":"45164970","full_name":"git-hulk/libtask-annotation","owner":"git-hulk","description":"libtask annotation","archived":false,"fork":false,"pushed_at":"2016-07-30T15:10:26.000Z","size":48,"stargazers_count":25,"open_issues_count":0,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-15T03:37:38.673Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/git-hulk.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-10-29T06:36:31.000Z","updated_at":"2019-12-29T03:16:37.000Z","dependencies_parsed_at":"2023-06-07T03:45:37.380Z","dependency_job_id":null,"html_url":"https://github.com/git-hulk/libtask-annotation","commit_stats":{"total_commits":11,"total_committers":2,"mean_commits":5.5,"dds":0.09090909090909094,"last_synced_commit":"83e2ef95ca6a9f662de5fba5fae1732e81d89ec3"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/git-hulk/libtask-annotation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-hulk%2Flibtask-annotation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-hulk%2Flibtask-annotation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-hulk%2Flibtask-annotation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-hulk%2Flibtask-annotation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/git-hulk","download_url":"https://codeload.github.com/git-hulk/libtask-annotation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-hulk%2Flibtask-annotation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264192315,"owners_count":23570759,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T11:14:51.101Z","updated_at":"2025-07-08T04:06:59.387Z","avatar_url":"https://github.com/git-hulk.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"Libtask is a simple coroutine library.  It runs on Linux (ARM, MIPS, and x86),\nFreeBSD (x86), OS X (PowerPC x86, and x86-64), and SunOS Solaris (Sparc),\nand is easy to port to other systems.\n\nLibtask gives the programmer the illusion of threads, but\nthe operating system sees only a single kernel thread.\nFor clarity, we refer to the coroutines as \"tasks,\" not threads.\n\nScheduling is cooperative.  Only one task runs at a time,\nand it cannot be rescheduled without explicitly giving up\nthe CPU.  Most of the functions provided in task.h do have\nthe possibility of going to sleep.  Programs using the task\nfunctions should #include \u003ctask.h\u003e.\n\n--- Basic task manipulation\n\nint taskcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);\n\n\tCreate a new task running f(arg) on a stack of size stacksize.\n\nvoid tasksystem(void);\n\n\tMark the current task as a \"system\" task.  These are ignored\n\tfor the purposes of deciding the program is done running\n\t(see taskexit next).\n\t\nvoid taskexit(int status);\n\n\tExit the current task.  If this is the last non-system task,\n\texit the entire program using the given exit status.\n\nvoid taskexitall(int status);\n\n\tExit the entire program, using the given exit status.\n\nvoid taskmain(int argc, char *argv[]);\n\n\tWrite this function instead of main.  Libtask provides its own main.\n\nint taskyield(void);\n\t\n\tExplicitly give up the CPU.  The current task will be scheduled\n\tagain once all the other currently-ready tasks have a chance\n\tto run.  Returns the number of other tasks that ran while the\n\tcurrent task was waiting.  (Zero means there are no other tasks\n\ttrying to run.)\n\nint taskdelay(unsigned int ms)\n\n\tExplicitly give up the CPU for at least ms milliseconds.\n\tOther tasks continue to run during this time.\n\nvoid** taskdata(void);\n\n\tReturn a pointer to a single per-task void* pointer.\n\tYou can use this as a per-task storage place.\n\nvoid needstack(int n);\n\n\tTell the task library that you need at least n bytes left\n\ton the stack.  If you don't have it, the task library will call abort.\n\t(It's hard to figure out how big stacks should be.  I usually make\n\tthem really big (say 32768) and then don't worry about it.)\n\nvoid taskname(char*, ...);\n\n\tTakes an argument list like printf.  Sets the current task's name.\n\t\nchar* taskgetname(void);\n\n\tReturns the current task's name.  Is the actual buffer; do not free.\n\t\nvoid taskstate(char*, ...);\nchar* taskgetstate(void);\n\n\tLike taskname and taskgetname but for the task state.\n\t\n\tWhen you send a tasked program a SIGQUIT (or SIGINFO, on BSD)\n\tit will print a list of all its tasks and their names and states.\n\tThis is useful for debugging why your program isn't doing anything!\n\nunsigned int taskid(void);\n\n\tReturn the unique task id for the current task.\n\n--- Non-blocking I/O\n\nThere is a small amount of runtime support for non-blocking I/O\non file descriptors.  \n\nint fdnoblock(int fd);\n\n\tSets I/O on the given fd to be non-blocking.  Should be\n\tcalled before any of the other fd routines.\n\nint fdread(int, void*, int);\n\n\tLike regular read(), but puts task to sleep while waiting for\n\tdata instead of blocking the whole program.\n\nint fdwrite(int, void*, int);\n\n\tLike regular write(), but puts task to sleep while waiting to\n\twrite data instead of blocking the whole program.\n\nvoid fdwait(int fd, int rw);\n\n\tLow-level call sitting underneath fdread and fdwrite.\n\tPuts task to sleep while waiting for I/O to be possible on fd.\n\tRw specifies type of I/O: 'r' means read, 'w' means write,\n\tanything else means just exceptional conditions (hang up, etc.)\n\tThe 'r' and 'w' also wake up for exceptional conditions.\n\n--- Network I/O\n\nThese are convenient packaging of the ugly Unix socket routines.\nThey can all put the current task to sleep during the call.  \n\nint netannounce(int proto, char *address, int port)\n\n\tStart a network listener running on address and port of protocol.\n\tProto is either TCP or UDP.  Port is a port number.  Address is a\n\tstring version of a host name or IP address.  If address is null,\n\tthen announce binds to the given port on all available interfaces.\n\tReturns a fd to use with netaccept.\n\tExamples: netannounce(TCP, \"localhost\", 80) or \n\t\tnetannounce(TCP, \"127.0.0.1\", 80) or netannounce(TCP, 0, 80).\n\nint netaccept(int fd, char *server, int *port)\n\n\tGet the next connection that comes in to the listener fd.\n\tReturns a fd to use to talk to the guy who just connected.\n\tIf server is not null, it must point at a buffer of at least\n\t16 bytes that is filled in with the remote IP address.\n\tIf port is not null, it is filled in with the report port.\n\tExample:\n\t\tchar server[16];\n\t\tint port;\n\t\t\n\t\tif(netaccept(fd, server, \u0026port) \u003e= 0)\n\t\t\tprintf(\"connect from %s:%d\", server, port);\n\nint netdial(int proto, char *name, int port)\n\n\tCreate a new (outgoing) connection to a particular host.\n\tName can be an ip address or a domain name.  If it's a domain name,\n\tthe entire program will block while the name is resolved\n\t(the DNS library does not provide a nice non-blocking interface).\n\tExample: netdial(TCP, \"www.google.com\", 80)\n\t\tor netdial(TCP, \"18.26.4.9\", 80)\n\n--- Time\n\nunsigned int taskdelay(unsigned int ms)\n\n\tPut the current task to sleep for approximately ms milliseconds.\n\tReturn the actual amount of time slept, in milliseconds.\n\n--- Example programs\n\nIn this directory, tcpproxy.c is a simple TCP proxy that illustrates\nmost of the above.  You can run\n\n\ttcpproxy 1234 www.google.com 80\n\nand then you should be able to visit http://localhost:1234/ and see Google.\n\nOther examples are:\n\tprimes.c - simple prime sieve\n\thttpload.c - simple HTTP load generator\n\ttestdelay.c - test taskdelay()\n\n--- Building\n\nTo build, run make.  You can run make install to copy task.h and\nlibtask.a to the appropriate places in /usr/local.  Then you\nshould be able to just link with -ltask in your programs\nthat use it.  \n\nOn SunOS Solaris machines, run makesun instead of just make.\n\n--- Contact Info\n\nPlease email me with questions or problems.\n\nRuss Cox\nrsc@swtch.com\n\n\n--- Stuff you probably won't use at first ---\n--- but might want to know about eventually ---\n\nvoid tasksleep(Rendez*);\nint taskwakeup(Rendez*);\nint taskwakeupall(Rendez*);\n\n\tA Rendez is a condition variable. You can declare a new one by\n\tjust allocating memory for it (or putting it in another structure)\n\tand then zeroing the memory.  Tasksleep(r) 'sleeps on r', giving\n\tup the CPU.  Multiple tasks can sleep on a single Rendez.\n\tWhen another task comes along and calls taskwakeup(r), \n\tthe first task sleeping on r (if any) will be woken up.\n\tTaskwakeupall(r) wakes up all the tasks sleeping on r.\n\tThey both return the actual number of tasks awakened.\n\n\n\nvoid qlock(QLock*);\nint canqlock(QLock*);\nvoid qunlock(QLock*);\n\n\tYou probably won't need locks because of the cooperative \n\tscheduling, but if you do, here are some.  You can make a new\n\tQLock by just declaring it and zeroing the memory.\n\tCalling qlock will give up the CPU if the lock is held by someone else.\n\tCalling qunlock will not give up the CPU.\n\tCalling canqlock tries to lock the lock, but will not give up the CPU.\n\tIt returns 1 if the lock was acquired, 0 if it cannot be at this time.\n\nvoid rlock(RWLock*);\nint canrlock(RWLock*);\nvoid runlock(RWLock*);\n\nvoid wlock(RWLock*);\nint canwlock(RWLock*);\nvoid wunlock(RWLock*);\n\n\tRWLocks are reader-writer locks.  Any number of readers\n\tcan lock them at once, but only one writer at a time.\n\tIf a writer is holding it, there can't be any readers.\n\t\n\nChannel *chancreate(int, int);\netc.\n\n\tChannels are buffered communication pipes you can\n\tuse to send messages between tasks.  Some people like\n\tdoing most of the inter-task communication using channels.\n\t\n\tFor details on channels see the description of channels in\n\thttp://swtch.com/usr/local/plan9/man/man3/thread.html and\n\thttp://swtch.com/~rsc/thread/\n\tand also the example program primes.c, which implements\n\ta concurrent prime sieve.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-hulk%2Flibtask-annotation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgit-hulk%2Flibtask-annotation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-hulk%2Flibtask-annotation/lists"}