From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5693 Path: news.gmane.org!not-for-mail From: Szabolcs Nagy Newsgroups: gmane.linux.lib.musl.general Subject: Re: working C11 thread implementation Date: Fri, 1 Aug 2014 23:08:46 +0200 Message-ID: <20140801210846.GA22308@port70.net> References: <1406886931.4830.92.camel@eris.loria.fr> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1406927354 8996 80.91.229.3 (1 Aug 2014 21:09:14 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 1 Aug 2014 21:09:14 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5698-gllmg-musl=m.gmane.org@lists.openwall.com Fri Aug 01 23:09:03 2014 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XDK4R-0002Wd-QL for gllmg-musl@plane.gmane.org; Fri, 01 Aug 2014 23:08:59 +0200 Original-Received: (qmail 5912 invoked by uid 550); 1 Aug 2014 21:08:58 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 5904 invoked from network); 1 Aug 2014 21:08:58 -0000 Mail-Followup-To: musl@lists.openwall.com Content-Disposition: inline In-Reply-To: <1406886931.4830.92.camel@eris.loria.fr> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:5693 Archived-At: * Jens Gustedt [2014-08-01 11:55:31 +0200]: > for anybody interested I attach a first working version, that is > mildly tested with a relatively big private application that I have > and that uses C11 threads quite intensively. nice > The choices that affect the ABI that I mentioned are values of some > constants and the sizes of the types that are introduced. These may > change depending on glibc's choices and also according to future > developments. > > For the choices of the constants, for this version they are such that > most wrapper calls result in being tail calls. I verified this by > looking into the assembler that is produced. As they are now, most of > these tail functions could also be just provided as weak aliases. We > chose to implement them as functions such that in case of change of > the constants we only have to recompile and no other maintenance is > required. > i'd assume the constants to be right and fix up the code only in case of later breakage > + /* The following list of 9 integer constants makes up for the binary > + compatibility of this C thread implementation. You must never > + link code against versions of the C library that do not agree > + upon these ABI parameters. nice > +int cnd_signal(cnd_t * cnd) { > + /* In the best of all worlds this is a tail call. */ > + int ret = __pthread_cond_signal(cnd); > + if (thrd_success) > + return ret ? thrd_error : thrd_success; > + return ret; > +} this is a bit weird i think it's better to just assume thrd_success==0 and static assert it somewhere as a reminder > +int mtx_init(mtx_t * m, int type) > +{ > + *m = (pthread_mutex_t) { > + ._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : 0), > + }; > + return 0; > +} return thrd_success > +/* This is needed because not all arch have __pthread_self as a static > + symbol. */ > pthread_t pthread_self() > { > return __pthread_self(); ... > +/* This is needed because not all arch have __pthread_self as a static > + symbol. */ > +pthread_t thrd_current() > +{ > + return __pthread_self(); > +} i dont understand these comments you mean that they could be weak aliases otherwise? > +int thrd_join(thrd_t t, int *res) > +{ > + int tmp; > + while ((tmp = t->tid)) __timedwait(&t->tid, tmp, 0, 0, 0, 0, 0); > + if (res) *res = (int)(intptr_t)t->result; > + if (t->map_base) munmap(t->map_base, t->map_size); > + return 0; > +} thrd_success > +int tss_set(tss_t k, void *x) > +{ > + struct pthread *self = __pthread_self(); > + /* Avoid unnecessary COW */ > + if (self->tsd[k] != x) { > + self->tsd[k] = x; > + self->tsd_used = 1; > + } > + return 0; > +} thrd_success > +/* Roughly __syscall already returns the right thing: 0 if all went > + well or a negative error indication, otherwise. Unfortunately the C > + standard foresees the special case of an interrupted call and fixes > + that error return to -1 (instead of introducing EINTR). */ > +int thrd_sleep(const struct timespec *req, struct timespec *rem) > +{ > + int ret = __syscall(SYS_nanosleep, req, rem); > + // compile time comparison, constant propagated > + if (EINTR != 1) { > + switch (ret) { > + case -EINTR: return -1; > + case -1: return -EINTR; > + } > + } > + // potentially a tail call > + return ret; > +} "The thrd_sleep function returns zero if the requested time has elapsed, -1 if it has been interrupted by a signal, or a negative value if it fails." this is confusing (either should not have the name thrd_ or follow the error enum convention of other thrd_ functions)