From c548cce5a15b815f2b3331ce3a9c45512f5bf8a8 Mon Sep 17 00:00:00 2001 From: leitner Date: Sat, 29 Mar 2014 11:17:04 +0000 Subject: [PATCH] another attempt at a thread-safe array --- GNUmakefile | 10 +++--- Makefile | 62 +++++++++++++++++++++----------- array/iarray_allocate.c | 78 +++++++++++++++-------------------------- array/iarray_free.c | 17 +++++++-- array/iarray_get.c | 15 ++++---- array/iarray_init.c | 14 +++----- iarray.h | 25 +++++++------ textcode.h | 6 +++- 8 files changed, 118 insertions(+), 109 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index fdd4ad4..ba31ec3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -21,8 +21,8 @@ CC=$(CROSS)gcc CFLAGS=-pipe -W -Wall -Wextra -O2 -fomit-frame-pointer #CFLAGS=-pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall -ent: ent.c - gcc -g -o ent ent.c +ent: ent.c haveuint128.h + gcc -g -o ent ent.c -I. # CFLAGS += -fstrict-aliasing -Wstrict-aliasing=2 @@ -76,7 +76,7 @@ TAI_OBJS=$(patsubst tai/%.c,%.o,$(wildcard tai/*.c)) TAIA_OBJS=$(patsubst taia/%.c,%.o,$(wildcard taia/*.c)) DNS_OBJS=$(patsubst dns/%.c,%.o,$(wildcard dns/*.c)) CASE_OBJS=$(patsubst case/%.c,%.o,$(wildcard case/*.c)) -ARRAY_OBJS=$(patsubst array/%.c,%.o,$(wildcard array/array_*.c)) +ARRAY_OBJS=$(patsubst array/%.c,%.o,$(wildcard array/*.c)) MULT_OBJS=$(patsubst mult/%.c,%.o,$(wildcard mult/*.c)) IO_OBJS=$(patsubst io/%.c,%.o,$(wildcard io/*.c)) CDB_OBJS=$(patsubst cdb/%.c,%.o,$(wildcard cdb/*.c)) @@ -139,7 +139,7 @@ $(TAIA_OBJS) $(TAI_OBJS) $(CASE_OBJS) $(ARRAY_OBJS) $(MULT_OBJS) \ $(IO_OBJS) $(CDB_OBJS) libowfat.a: $(ALL_OBJS) - $(CROSS)ar cr $@ $(ALL_OBJS) + $(CROSS)ar cru $@ $(ALL_OBJS) -$(CROSS)ranlib $@ CFLAGS+=-I. @@ -148,7 +148,7 @@ CFLAGS+=-I. $(DIET) $(CC) -c $< $(CFLAGS) %.a: - ar cr $@ $^ + ar cru $@ $^ -ranlib $@ t.o: t.c fmt.h scan.h str.h uint16.h uint32.h stralloc.h socket.h \ diff --git a/Makefile b/Makefile index c3d3add..2389da1 100644 --- a/Makefile +++ b/Makefile @@ -14,17 +14,21 @@ LIBS=byte.a fmt.a scan.a str.a uint.a open.a stralloc.a unix.a socket.a \ buffer.a mmap.a taia.a tai.a dns.a case.a mult.a array.a io.a \ textcode.a cdb.a -all: $(LIBS) libowfat.a libsocket t +all: ent $(LIBS) libowfat.a libsocket t CROSS= #CROSS=i686-mingw- CC=$(CROSS)gcc -CFLAGS=-pipe -W -Wall -O2 -fomit-frame-pointer +CFLAGS=-pipe -W -Wall -Wextra -O2 -fomit-frame-pointer #CFLAGS=-pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall +ent: ent.c haveuint128.h + gcc -g -o ent ent.c -I. + # CFLAGS += -fstrict-aliasing -Wstrict-aliasing=2 -CFLAGS += -D_REENTRANT +WERROR= +CFLAGS += -D_REENTRANT $(WERROR) array_allocate.o: array/array_allocate.c likely.h safemult.h uint16.h \ uint32.h uint64.h array.h byte.h @@ -57,6 +61,7 @@ buffer_2.o: buffer/buffer_2.c buffer.h buffer_close.o: buffer/buffer_close.c buffer.h buffer_feed.o: buffer/buffer_feed.c buffer.h buffer_flush.o: buffer/buffer_flush.c buffer.h +buffer_free.o: buffer/buffer_free.c buffer.h buffer_fromarray.o: buffer/buffer_fromarray.c array.h uint64.h buffer.h buffer_frombuf.o: buffer/buffer_frombuf.c stralloc.h buffer.h buffer_fromsa.o: buffer/buffer_fromsa.c stralloc.h buffer.h @@ -80,6 +85,7 @@ buffer_getnewline_sa.o: buffer/buffer_getnewline_sa.c stralloc.h buffer.h buffer_init.o: buffer/buffer_init.c buffer.h buffer_init_free.o: buffer/buffer_init_free.c buffer.h buffer_mmapread.o: buffer/buffer_mmapread.c buffer.h mmap.h +buffer_munmap.o: buffer/buffer_munmap.c buffer.h buffer_peek.o: buffer/buffer_peek.c buffer.h buffer_put.o: buffer/buffer_put.c byte.h buffer.h buffer_put8long.o: buffer/buffer_put8long.c buffer.h fmt.h byte.h @@ -129,6 +135,7 @@ cdb.o: cdb/cdb.c byte.h cdb.h uint32.h uint64.h cdb_hash.o: cdb/cdb_hash.c cdb.h uint32.h uint64.h cdb_make.o: cdb/cdb_make.c cdb.h uint32.h uint64.h cdb_make.h buffer.h cdb_traverse.o: cdb/cdb_traverse.c cdb.h uint32.h uint64.h +critbit.o: critbit/critbit.c dns_dfd.o: dns/dns_dfd.c byte.h dns.h stralloc.h iopause.h taia.h tai.h \ uint64.h uint32.h dns_domain.o: dns/dns_domain.c case.h byte.h dns.h stralloc.h iopause.h \ @@ -178,6 +185,14 @@ fmt_8longlong.o: fmt/fmt_8longlong.c fmt.h byte.h fmt_asn1derlength.o: fmt/fmt_asn1derlength.c fmt.h byte.h fmt_asn1dertag.o: fmt/fmt_asn1dertag.c fmt.h byte.h fmt_double.o: fmt/fmt_double.c fmt.h byte.h +fmt_escapecharc.o: fmt/fmt_escapecharc.c fmt.h byte.h +fmt_escapecharhtml.o: fmt/fmt_escapecharhtml.c +fmt_escapecharjson.o: fmt/fmt_escapecharjson.c fmt.h byte.h +fmt_escapecharquotedprintable.o: fmt/fmt_escapecharquotedprintable.c \ + fmt.h byte.h +fmt_escapecharquotedprintableutf8.o: \ + fmt/fmt_escapecharquotedprintableutf8.c fmt.h byte.h +fmt_escapecharxml.o: fmt/fmt_escapecharxml.c fmt.h byte.h fmt_fill.o: fmt/fmt_fill.c fmt.h byte.h fmt_httpdate.o: fmt/fmt_httpdate.c fmt.h byte.h byte.h fmt_human.o: fmt/fmt_human.c fmt.h byte.h @@ -197,6 +212,7 @@ fmt_ulonglong.o: fmt/fmt_ulonglong.c fmt.h byte.h fmt_utf8.o: fmt/fmt_utf8.c fmt.h byte.h fmt_xlong.o: fmt/fmt_xlong.c fmt.h byte.h haveinline.h fmt_xlonglong.o: fmt/fmt_xlonglong.c fmt.h byte.h +fmt_xmlescape.o: fmt/fmt_xmlescape.c fmt.h byte.h io_appendfile.o: io/io_appendfile.c io_internal.h io.h uint64.h taia.h \ tai.h uint32.h array.h haveepoll.h havekqueue.h havedevpoll.h \ havesigio.h @@ -260,9 +276,6 @@ io_sigpipe.o: io/io_sigpipe.c io_internal.h io.h uint64.h taia.h tai.h \ io_socketpair.o: io/io_socketpair.c windoze.h io_internal.h io.h uint64.h \ taia.h tai.h uint32.h array.h haveepoll.h havekqueue.h havedevpoll.h \ havesigio.h -io_starteventloop.o: io/io_starteventloop.c io_internal.h io.h uint64.h \ - taia.h tai.h uint32.h array.h haveepoll.h havekqueue.h havedevpoll.h \ - havesigio.h io_timeout.o: io/io_timeout.c io_internal.h io.h uint64.h taia.h tai.h \ uint32.h array.h haveepoll.h havekqueue.h havedevpoll.h havesigio.h io_timeouted.o: io/io_timeouted.c io_internal.h io.h uint64.h taia.h \ @@ -354,6 +367,7 @@ openreadclose.o: open/openreadclose.c open.h readclose.h stralloc.h \ readclose.o: open/readclose.c readclose.h stralloc.h scan_8int.o: scan/scan_8int.c scan.h scan_8long.o: scan/scan_8long.c scan.h +scan_8longlong.o: scan/scan_8longlong.c scan.h scan_8longn.o: scan/scan_8longn.c scan.h scan_8short.o: scan/scan_8short.c scan.h scan_asn1derlength.o: scan/scan_asn1derlength.c scan.h @@ -374,7 +388,7 @@ scan_short.o: scan/scan_short.c scan.h scan_uint.o: scan/scan_uint.c scan.h scan_ulong.o: scan/scan_ulong.c scan.h scan_ulonglong.o: scan/scan_ulonglong.c scan.h -scan_ulongn.o: scan/scan_ulongn.c scan.h +scan_ulongn.o: scan/scan_ulongn.c scan.h haveuint128.h scan_ushort.o: scan/scan_ushort.c scan.h scan_utf8.o: scan/scan_utf8.c fmt.h byte.h scan_whitenskip.o: scan/scan_whitenskip.c scan.h @@ -385,7 +399,8 @@ scan_xlongn.o: scan/scan_xlongn.c scan.h scan_xshort.o: scan/scan_xshort.c scan.h fmt_ip4.o: socket/fmt_ip4.c fmt.h byte.h ip4.h fmt_ip6.o: socket/fmt_ip6.c fmt.h byte.h byte.h ip4.h ip6.h uint32.h -fmt_ip6_flat.o: socket/fmt_ip6_flat.c ip6.h byte.h uint32.h haveinline.h +fmt_ip6_flat.o: socket/fmt_ip6_flat.c ip6.h byte.h uint32.h haveinline.h \ + fmt.h fmt_ip6c.o: socket/fmt_ip6c.c fmt.h byte.h byte.h ip4.h ip6.h uint32.h fmt_ip6if.o: socket/fmt_ip6if.c ip6.h byte.h uint32.h str.h fmt.h \ socket.h uint16.h @@ -536,6 +551,8 @@ fmt_hexdump.o: textcode/fmt_hexdump.c fmt.h byte.h textcode.h str.h \ haveinline.h fmt_html.o: textcode/fmt_html.c fmt.h byte.h textcode.h str.h \ haveinline.h +fmt_jsonescape.o: textcode/fmt_jsonescape.c fmt.h byte.h textcode.h str.h \ + haveinline.h fmt_ldapescape.o: textcode/fmt_ldapescape.c fmt.h byte.h textcode.h \ haveinline.h str.h fmt_ldapescape2.o: textcode/fmt_ldapescape2.c fmt.h byte.h textcode.h \ @@ -554,8 +571,10 @@ fmt_yenc.o: textcode/fmt_yenc.c fmt.h byte.h textcode.h scan_base64.o: textcode/scan_base64.c textcode.h haveinline.h scan_cescape.o: textcode/scan_cescape.c fmt.h byte.h textcode.h scan.h scan_hexdump.o: textcode/scan_hexdump.c fmt.h byte.h textcode.h scan.h -scan_html.o: textcode/scan_html.c fmt.h byte.h textcode.h haveinline.h \ - case.h +scan_html.o: textcode/scan_html.c entities.h fmt.h byte.h textcode.h \ + haveinline.h scan.h case.h str.h +scan_jsonescape.o: textcode/scan_jsonescape.c fmt.h byte.h textcode.h \ + scan.h scan_ldapescape.o: textcode/scan_ldapescape.c fmt.h byte.h textcode.h \ scan.h scan_quotedprintable.o: textcode/scan_quotedprintable.c fmt.h byte.h \ @@ -596,25 +615,25 @@ t.o: t.c fmt.h byte.h scan.h str.h uint16.h uint32.h stralloc.h socket.h \ buffer.h ip4.h ip6.h mmap.h open.h textcode.h dns.h iopause.h taia.h \ tai.h uint64.h case.h errmsg.h iob.h io.h array.h safemult.h iarray.h \ CAS.h io_internal.h haveepoll.h havekqueue.h havedevpoll.h havesigio.h -BYTE_OBJS=byte_chr.o byte_copy.o byte_copyr.o byte_diff.o byte_rchr.o byte_zero.o -FMT_OBJS=fmt_8long.o fmt_8longlong.o fmt_double.o fmt_fill.o fmt_httpdate.o fmt_human.o fmt_humank.o fmt_long.o fmt_longlong.o fmt_minus.o fmt_pad.o fmt_plusminus.o fmt_str.o fmt_strm_internal.o fmt_strn.o fmt_tohex.o fmt_ulong.o fmt_ulong0.o fmt_ulonglong.o fmt_xlong.o fmt_xlonglong.o -SCAN_OBJS=scan_8int.o scan_8long.o scan_8short.o scan_charsetnskip.o scan_double.o scan_fromhex.o scan_httpdate.o scan_int.o scan_long.o scan_longlong.o scan_noncharsetnskip.o scan_nonwhitenskip.o scan_plusminus.o scan_short.o scan_uint.o scan_ulong.o scan_ulonglong.o scan_ushort.o scan_whitenskip.o scan_xint.o scan_xlong.o scan_xlonglong.o scan_xshort.o +BYTE_OBJS=byte_chr.o byte_copy.o byte_copyr.o byte_diff.o byte_equal_notimingattack.o byte_rchr.o byte_zero.o +FMT_OBJS=fmt_8long.o fmt_8longlong.o fmt_asn1derlength.o fmt_asn1dertag.o fmt_double.o fmt_escapecharc.o fmt_escapecharhtml.o fmt_escapecharjson.o fmt_escapecharquotedprintable.o fmt_escapecharquotedprintableutf8.o fmt_escapecharxml.o fmt_fill.o fmt_httpdate.o fmt_human.o fmt_humank.o fmt_long.o fmt_longlong.o fmt_minus.o fmt_pad.o fmt_plusminus.o fmt_str.o fmt_strm_internal.o fmt_strn.o fmt_tohex.o fmt_ulong.o fmt_ulong0.o fmt_ulonglong.o fmt_utf8.o fmt_xlong.o fmt_xlonglong.o fmt_xmlescape.o +SCAN_OBJS=scan_8int.o scan_8long.o scan_8longlong.o scan_8longn.o scan_8short.o scan_asn1derlength.o scan_asn1dertag.o scan_charsetnskip.o scan_double.o scan_fromhex.o scan_httpdate.o scan_int.o scan_long.o scan_longlong.o scan_longn.o scan_netstring.o scan_noncharsetnskip.o scan_nonwhitenskip.o scan_plusminus.o scan_short.o scan_uint.o scan_ulong.o scan_ulonglong.o scan_ulongn.o scan_ushort.o scan_utf8.o scan_whitenskip.o scan_xint.o scan_xlong.o scan_xlonglong.o scan_xlongn.o scan_xshort.o STR_OBJS=str_chr.o str_copy.o str_diff.o str_diffn.o str_len.o str_rchr.o str_start.o UINT_OBJS=uint16_pack.o uint16_pack_big.o uint16_read.o uint16_read_big.o uint16_unpack.o uint16_unpack_big.o uint32_pack.o uint32_pack_big.o uint32_read.o uint32_read_big.o uint32_unpack.o uint32_unpack_big.o uint64_pack.o uint64_pack_big.o uint64_read.o uint64_read_big.o uint64_unpack.o uint64_unpack_big.o OPEN_OBJS=open_append.o open_excl.o open_read.o open_rw.o open_trunc.o open_write.o openreadclose.o readclose.o STRALLOC_OBJS=stralloc_append.o stralloc_cat.o stralloc_catb.o stralloc_catlong0.o stralloc_catm_internal.o stralloc_cats.o stralloc_catulong0.o stralloc_chomp.o stralloc_chop.o stralloc_copy.o stralloc_copyb.o stralloc_copys.o stralloc_diff.o stralloc_diffs.o stralloc_free.o stralloc_init.o stralloc_ready.o stralloc_readyplus.o stralloc_starts.o stralloc_zero.o UNIX_OBJS=iopause.o ndelay_off.o ndelay_on.o winsock2errno.o -SOCKET_OBJS=fmt_ip4.o fmt_ip6.o fmt_ip6_flat.o fmt_ip6c.o fmt_ip6if.o fmt_ip6ifc.o init.o scan_ip4.o scan_ip6.o scan_ip6_flat.o scan_ip6if.o socket_accept4.o socket_accept6.o socket_bind4.o socket_bind4_reuse.o socket_bind6.o socket_bind6_reuse.o socket_broadcast.o socket_connect4.o socket_connect6.o socket_connected.o socket_deferaccept.o socket_getifidx.o socket_getifname.o socket_ip4loopback.o socket_listen.o socket_local4.o socket_local6.o socket_mchopcount6.o socket_mcjoin4.o socket_mcjoin6.o socket_mcleave4.o socket_mcleave6.o socket_mcloop4.o socket_mcloop6.o socket_mcttl4.o socket_noipv6.o socket_recv4.o socket_recv6.o socket_remote4.o socket_remote6.o socket_send4.o socket_send6.o socket_tcp4.o socket_tcp4b.o socket_tcp6.o socket_tcp6b.o socket_tryreservein.o socket_udp4.o socket_udp6.o socket_v4mappedprefix.o socket_v6any.o socket_v6loopback.o -BUFFER_OBJS=buffer_0.o buffer_0small.o buffer_1.o buffer_1small.o buffer_2.o buffer_close.o buffer_feed.o buffer_flush.o buffer_fromsa.o buffer_get.o buffer_get_new_token_sa.o buffer_get_new_token_sa_pred.o buffer_get_token.o buffer_get_token_pred.o buffer_get_token_sa.o buffer_get_token_sa_pred.o buffer_getc.o buffer_getline.o buffer_getline_sa.o buffer_getn.o buffer_getnewline_sa.o buffer_init.o buffer_init_free.o buffer_mmapread.o buffer_peek.o buffer_put.o buffer_put8long.o buffer_putalign.o buffer_puterror.o buffer_puterror2.o buffer_putflush.o buffer_putlong.o buffer_putlonglong.o buffer_putm_internal.o buffer_putm_internal_flush.o buffer_putnlflush.o buffer_puts.o buffer_putsa.o buffer_putsaflush.o buffer_putsalign.o buffer_putsflush.o buffer_putspace.o buffer_putulong.o buffer_putulonglong.o buffer_putxlong.o buffer_seek.o buffer_stubborn.o buffer_stubborn2.o buffer_tosa.o errmsg_iam.o errmsg_info.o errmsg_infosys.o errmsg_puts.o errmsg_warn.o errmsg_warnsys.o errmsg_write.o +SOCKET_OBJS=fmt_ip4.o fmt_ip6.o fmt_ip6_flat.o fmt_ip6c.o fmt_ip6if.o fmt_ip6ifc.o init.o scan_ip4.o scan_ip6.o scan_ip6_flat.o scan_ip6if.o socket_accept4.o socket_accept6.o socket_bind4.o socket_bind4_reuse.o socket_bind6.o socket_bind6_reuse.o socket_broadcast.o socket_connect4.o socket_connect6.o socket_connected.o socket_deferaccept.o socket_getifidx.o socket_getifname.o socket_ip4loopback.o socket_listen.o socket_local4.o socket_local6.o socket_mchopcount6.o socket_mcjoin4.o socket_mcjoin6.o socket_mcleave4.o socket_mcleave6.o socket_mcloop4.o socket_mcloop6.o socket_mcttl4.o socket_noipv6.o socket_recv4.o socket_recv6.o socket_remote4.o socket_remote6.o socket_sctp4.o socket_sctp4b.o socket_sctp6.o socket_sctp6b.o socket_send4.o socket_send6.o socket_tcp4.o socket_tcp4b.o socket_tcp6.o socket_tcp6b.o socket_tryreservein.o socket_udp4.o socket_udp6.o socket_v4mappedprefix.o socket_v6any.o socket_v6loopback.o +BUFFER_OBJS=buffer_0.o buffer_0small.o buffer_1.o buffer_1small.o buffer_2.o buffer_close.o buffer_feed.o buffer_flush.o buffer_free.o buffer_fromarray.o buffer_frombuf.o buffer_fromsa.o buffer_get.o buffer_get_new_token_sa.o buffer_get_new_token_sa_pred.o buffer_get_token.o buffer_get_token_pred.o buffer_get_token_sa.o buffer_get_token_sa_pred.o buffer_getc.o buffer_getline.o buffer_getline_sa.o buffer_getn.o buffer_getnewline_sa.o buffer_init.o buffer_init_free.o buffer_mmapread.o buffer_munmap.o buffer_peek.o buffer_put.o buffer_put8long.o buffer_putalign.o buffer_puterror.o buffer_puterror2.o buffer_putflush.o buffer_putlong.o buffer_putlonglong.o buffer_putm_internal.o buffer_putm_internal_flush.o buffer_putnlflush.o buffer_puts.o buffer_putsa.o buffer_putsaflush.o buffer_putsalign.o buffer_putsflush.o buffer_putspace.o buffer_putulong.o buffer_putulonglong.o buffer_putxlong.o buffer_seek.o buffer_stubborn.o buffer_stubborn2.o buffer_tosa.o errmsg_iam.o errmsg_info.o errmsg_infosys.o errmsg_puts.o errmsg_warn.o errmsg_warnsys.o errmsg_write.o MMAP_OBJS=mmap_private.o mmap_read.o mmap_shared.o mmap_unmap.o TAIA_OBJS=taia_add.o taia_addsec.o taia_approx.o taia_frac.o taia_half.o taia_less.o taia_now.o taia_pack.o taia_sub.o taia_tai.o taia_uint.o taia_unpack.o TAI_OBJS=tai_add.o tai_now.o tai_pack.o tai_sub.o tai_uint.o tai_unpack.o DNS_OBJS=dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ip6.o dns_ipq.o dns_ipq6.o dns_mx.o dns_name.o dns_nd.o dns_nd6.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o dns_sortip.o dns_sortip6.o dns_transmit.o dns_txt.o CASE_OBJS=case_diffb.o case_diffs.o case_lowerb.o case_lowers.o case_starts.o MULT_OBJS=imult16.o imult32.o imult64.o range_arrayinbuf.o range_str2inbuf.o range_str4inbuf.o range_strinbuf.o umult16.o umult32.o umult64.o -ARRAY_OBJS=array_allocate.o array_bytes.o array_cat.o array_cat0.o array_catb.o array_cate.o array_cats.o array_cats0.o array_equal.o array_fail.o array_get.o array_length.o array_reset.o array_start.o array_trunc.o array_truncate.o +ARRAY_OBJS=array_allocate.o array_bytes.o array_cat.o array_cat0.o array_catb.o array_cate.o array_cats.o array_cats0.o array_equal.o array_fail.o array_get.o array_length.o array_reset.o array_start.o array_trunc.o array_truncate.o iarray_allocate.o iarray_free.o iarray_get.o iarray_init.o IO_OBJS=io_appendfile.o io_block.o io_canread.o io_canwrite.o io_check.o io_close.o io_closeonexec.o io_createfile.o io_dontwantread.o io_dontwantwrite.o io_eagain.o io_fd.o io_finishandshutdown.o io_getcookie.o io_mmapwritefile.o io_nonblock.o io_passfd.o io_pipe.o io_readfile.o io_readwritefile.o io_receivefd.o io_sendfile.o io_setcookie.o io_sigpipe.o io_socketpair.o io_timeout.o io_timeouted.o io_tryread.o io_tryreadtimeout.o io_trywrite.o io_trywritetimeout.o io_wait.o io_waitread.o io_waituntil.o io_waituntil2.o io_waitwrite.o io_wantread.o io_wantwrite.o iob_addbuf.o iob_addbuf_free.o iob_addbuf_internal.o iob_addbuf_munmap.o iob_addfile.o iob_addfile_close.o iob_adds.o iob_adds_free.o iob_bytesleft.o iob_free.o iob_new.o iob_prefetch.o iob_reset.o iob_send.o iob_write.o -TEXTCODE_OBJS=base64.o fmt_base64.o fmt_cescape.o fmt_foldwhitespace.o fmt_hexdump.o fmt_html.o fmt_ldapescape.o fmt_ldapescape2.o fmt_quotedprintable.o fmt_to_array.o fmt_to_sa.o fmt_tofrom_array.o fmt_urlencoded.o fmt_uuencoded.o fmt_yenc.o scan_base64.o scan_cescape.o scan_hexdump.o scan_html.o scan_ldapescape.o scan_quotedprintable.o scan_to_array.o scan_to_sa.o scan_tofrom_array.o scan_urlencoded.o scan_uuencoded.o scan_yenc.o +TEXTCODE_OBJS=base64.o fmt_base64.o fmt_cescape.o fmt_foldwhitespace.o fmt_hexdump.o fmt_html.o fmt_jsonescape.o fmt_ldapescape.o fmt_ldapescape2.o fmt_quotedprintable.o fmt_to_array.o fmt_to_sa.o fmt_tofrom_array.o fmt_urlencoded.o fmt_uuencoded.o fmt_yenc.o scan_base64.o scan_cescape.o scan_hexdump.o scan_html.o scan_jsonescape.o scan_ldapescape.o scan_quotedprintable.o scan_to_array.o scan_to_sa.o scan_tofrom_array.o scan_urlencoded.o scan_uuencoded.o scan_yenc.o CDB_OBJS=cdb.o cdb_hash.o cdb_make.o cdb_traverse.o byte.a: $(BYTE_OBJS) @@ -645,7 +664,7 @@ $(TAIA_OBJS) $(TAI_OBJS) $(CASE_OBJS) $(ARRAY_OBJS) $(MULT_OBJS) \ $(IO_OBJS) $(CDB_OBJS) libowfat.a: $(ALL_OBJS) - $(CROSS)ar cr $@ $(ALL_OBJS) + $(CROSS)ar cru $@ $(ALL_OBJS) -$(CROSS)ranlib $@ CFLAGS+=-I. @@ -654,7 +673,7 @@ CFLAGS+=-I. $(DIET) $(CC) -c $< $(CFLAGS) %.a: - ar cr $@ $^ + ar cru $@ $^ -ranlib $@ t.o: t.c fmt.h scan.h str.h uint16.h uint32.h stralloc.h socket.h \ @@ -698,7 +717,7 @@ uninstall: rm -f $(LIBDIR)/libowfat.a VERSION=libowfat-0.30 -CURNAME=libowfat-0.28 +CURNAME=libowfat-0.30 tar: clean rename rm -f dep libdep @@ -837,6 +856,9 @@ windoze: windoze64: $(MAKE) DIET= CROSS=x86_64-mingw32- +update: + dl -n http://www.w3.org/TR/html5/entities.json + entities.h: entities.json ent ./ent diff --git a/array/iarray_allocate.c b/array/iarray_allocate.c index deab547..5e5dc1a 100644 --- a/array/iarray_allocate.c +++ b/array/iarray_allocate.c @@ -1,59 +1,37 @@ #include "likely.h" #include +#include +#include +#include #include "iarray.h" - -void* iarray_allocate(iarray* ia,size_t pos) { - size_t y; - /* first the easy case without locking */ - if (__likely((y=pos/ia->elemperpage) < ia->pagefence && ia->pages[y])) - return ia->pages[y]+(pos%ia->elemperpage)*ia->elemsize; - /* the case where ia->pages == NULL is implicit */ - -#ifdef __MINGW32__ - EnterCriticalSection(&ia->cs); +#ifdef __dietlibc__ +#include #else - pthread_mutex_lock(&ia->m); +#define __CAS(ptr,oldval,newval) __sync_val_compare_and_swap(ptr,oldval,newval) #endif - if (__unlikely(y >= ia->pagefence)) { - char** np; - /* The data structure is an array of pointer to pages. - * Each page holds at least one element of the array. - * Here we realloc the array of pointers. Each element in this - * array is only 4 or 8 bytes, so we should allocate a few more than - * we need to cut down on future reallocs. */ - size_t z=(y+512)&-512; /* round up to multiple of 512 */ - /* It may seem as if there can be no integer overflow in the - * indirect index, because then the array would not fit into the - * address space in the first place, but remember that this is a - * sparse array. Someone might just pass in an unreasonable large - * index and have large elements, too */ - if (z==0) goto unlockandfail; /* integer overflow */ - np=realloc(ia->pages,z*ia->bytesperpage); - if (!np) goto unlockandfail; - ia->pagefence=z; - ia->pages=np; - } +static iarray_page* new_page(size_t pagesize) { + void* x=mmap(0,pagesize,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0); + if (x==MAP_FAILED) return 0; + return (iarray_page*)x; +} - /* at this point we know the slot exists */ - /* through a race between the early-out above and the - * pthread_mutex_lock, the page pointer to it could be non-NULL, - * however */ - if (__unlikely(ia->pages[y]==0 && (ia->pages[y]=malloc(ia->bytesperpage))==0)) { -unlockandfail: -#ifdef __MINGW32__ - LeaveCriticalSection(&ia->cs); -#else - pthread_mutex_unlock(&ia->m); -#endif - return 0; +void* iarray_allocate(iarray* ia,size_t pos) { + size_t index; + iarray_page** p=&ia->pages[pos%(sizeof(ia->pages)/sizeof(ia->pages[0]))]; + iarray_page* newpage=0; + for (index=0; poselemperpage; index+=ia->elemperpage) { + if (!*p) { + if (!newpage) + if (!(newpage=new_page(ia->bytesperpage))) return 0; + if (__CAS(p,0,newpage)==0) + newpage=0; + } + if (index+ia->elemperpage>pos) { + if (newpage) munmap(newpage,ia->bytesperpage); + return &(*p)->data[(pos-index)*ia->elemsize]; + } + p=&(*p)->next; } - -#ifdef __MINGW32__ - LeaveCriticalSection(&ia->cs); -#else - pthread_mutex_unlock(&ia->m); -#endif - - return ia->pages[y] + (pos%ia->elemperpage)*ia->elemsize; + return 0; // can't happen } diff --git a/array/iarray_free.c b/array/iarray_free.c index 7ea1393..f742316 100644 --- a/array/iarray_free.c +++ b/array/iarray_free.c @@ -1,9 +1,20 @@ #include +#include +#include #include "iarray.h" +static void freechain(iarray_page* p,size_t pagesize) { + while (p) { + iarray_page* n=p->next; + munmap(p,pagesize); + p=n; + } +} + void iarray_free(iarray* ia) { size_t i; - for (i=0; ipagefence; ++i) - if (ia->pages[i]) free(ia->pages[i]); - free(ia->pages); + for (i=0; ipages)/sizeof(ia->pages[0]); ++i) { + freechain(ia->pages[i],ia->bytesperpage); + ia->pages[i]=0; + } } diff --git a/array/iarray_get.c b/array/iarray_get.c index d578856..026abc4 100644 --- a/array/iarray_get.c +++ b/array/iarray_get.c @@ -1,12 +1,11 @@ #include "iarray.h" void* iarray_get(iarray* ia,size_t pos) { - char* x; - size_t y; - if (!ia->pages) return 0; - y=pos/ia->elemperpage; - if (y>=ia->pagefence) return 0; - x=ia->pages[y]; - if (!x) return 0; - return x+(pos%ia->elemperpage)*ia->elemsize; + size_t index; + iarray_page* p=ia->pages[pos%(sizeof(ia->pages)/sizeof(ia->pages[0]))]; + for (index=0; p; p=p->next, index+=ia->elemperpage) { + if (pos>=index && poselemperpage) + return &p->data[(pos-index)*ia->elemsize]; + } + return 0; } diff --git a/array/iarray_init.c b/array/iarray_init.c index d2ddc8b..f77bf71 100644 --- a/array/iarray_init.c +++ b/array/iarray_init.c @@ -1,20 +1,16 @@ #include "iarray.h" void iarray_init(iarray* ia,size_t elemsize) { + size_t i; ia->elemsize=elemsize; - ia->pages=0; - ia->pagefence=0; + for (i=0; ipages)/sizeof(ia->pages[0]); ++i) + ia->pages[i]=0; if (elemsize<1024) ia->bytesperpage=4096; else if (elemsize<8192) ia->bytesperpage=65536; else - ia->bytesperpage=elemsize; - ia->elemperpage=ia->bytesperpage/elemsize; -#ifdef __MINGW32__ - InitializeCriticalSection(&ia->cs); -#else - pthread_mutex_init(&ia->m,NULL); -#endif + ia->bytesperpage=elemsize+sizeof(void*); + ia->elemperpage=(ia->bytesperpage-sizeof(void*))/elemsize; } diff --git a/iarray.h b/iarray.h index 0a76e65..22e11ef 100644 --- a/iarray.h +++ b/iarray.h @@ -2,7 +2,12 @@ #ifndef IARRAY_H #define IARRAY_H -#warning DO NOT USE THIS YET. It may look thread-safe but it is not! +/* This header defines an indirect array for use with the io_* routines. + * Assumptions: + * - the elements are small (many fit on one page), + * - the platform has an atomic compare-and-swap instruction + * - the compiler supports it via __sync_val_compare_and_swap + */ #include "uint64.h" #include @@ -12,20 +17,14 @@ #include #endif -/* this is an indirect array; it only reallocs the indirect index, not - * the whole array. The actual data does not move. So there is no need - * to lock the array for read accesses. */ +typedef struct _iarray_page { + struct _iarray_page* next; + char data[]; +} iarray_page; typedef struct { - char** pages; - size_t elemsize,pagefence,elemperpage,bytesperpage; - /* pagefence is the number of pages + 1, - * i.e. the first out of bounds index in "pages" */ -#ifdef __MINGW32__ - CRITICAL_SECTION cs; -#else - pthread_mutex_t m; -#endif + iarray_page* pages[16]; + size_t elemsize,elemperpage,bytesperpage; } iarray; void iarray_init(iarray* ia,size_t elemsize); diff --git a/textcode.h b/textcode.h index bf6a089..4032c1b 100644 --- a/textcode.h +++ b/textcode.h @@ -45,7 +45,9 @@ size_t fmt_ldapescape2(char* dest,const char* src,size_t len,const char* escapem * Worst case: len*6 */ size_t fmt_jsonescape(char* dest,const char* src,size_t len); -/* These read one line from src, decoded it, and write the result to +size_t fmt_base85(char* dest,const char* src,size_t len); + +/* These read one line from src, decode it, and write the result to * dest. The number of decoded bytes is written to destlen. dest * should be able to hold strlen(src) bytes as a rule of thumb. */ size_t scan_uuencoded(const char *src,char *dest,size_t *destlen); @@ -60,6 +62,8 @@ size_t scan_cescape(const char *src,char *dest,size_t *destlen); size_t scan_ldapescape(const char* src,char* dest,size_t *destlen); size_t scan_jsonescape(const char* src,char* dest,size_t *destlen); +size_t scan_base85(const char* src,char* dest,size_t *destlen); + #ifdef STRALLOC_H /* WARNING: these functions _append_ to the stralloc, not overwrite! */ /* stralloc wrappers; return 1 on success, 0 on failure */