the "tracing" category in the configuration should only affect the "trace" sink and leave the "log" sink alone
Fixing that produces a lot of noise on stderr because of inappropriate use of the "info" category in various place and, on macOS, because of a rather stupid way of messing with thread scheduling priorities even when none have been specified explicitly in the configuration. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
29f0ef6e17
commit
c35c5f9190
18 changed files with 341 additions and 512 deletions
|
@ -77,7 +77,7 @@ dds_init(dds_domainid_t domain)
|
|||
dds_cfgst = config_init (uri);
|
||||
if (dds_cfgst == NULL)
|
||||
{
|
||||
DDS_ERROR("Failed to parse configuration XML file %s\n", uri);
|
||||
DDS_LOG(DDS_LC_CONFIG, "Failed to parse configuration XML file %s\n", uri);
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR);
|
||||
goto fail_config;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ dds_init(dds_domainid_t domain)
|
|||
|
||||
if (rtps_config_prep(dds_cfgst) != 0)
|
||||
{
|
||||
DDS_ERROR("Failed to configure RTPS\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "Failed to configure RTPS\n");
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR);
|
||||
goto fail_rtps_config;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ dds_init(dds_domainid_t domain)
|
|||
|
||||
if (rtps_init() < 0)
|
||||
{
|
||||
DDS_ERROR("Failed to initialize RTPS\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "Failed to initialize RTPS\n");
|
||||
ret = DDS_ERRNO(DDS_RETCODE_ERROR);
|
||||
goto fail_rtps_init;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ size_t dds_stream_check_optimize (_In_ const dds_topic_descriptor_t * desc)
|
|||
dds_sample_free_contents (sample, desc->m_ops);
|
||||
dds_free (sample);
|
||||
dds_stream_fini (&os);
|
||||
DDS_INFO("Marshalling for type: %s is%s optimised\n", desc->m_typename, size ? "" : " not");
|
||||
DDS_TRACE("Marshalling for type: %s is%s optimised\n", desc->m_typename, size ? "" : " not");
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (uint32_t port, ddsi_tran_qos_t
|
|||
uc->m_base.m_write_fn = ddsi_raweth_conn_write;
|
||||
uc->m_base.m_disable_multiplexing_fn = 0;
|
||||
|
||||
DDS_INFO("ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
|
||||
DDS_TRACE("ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
|
||||
return uc ? &uc->m_base : NULL;
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ static int ddsi_raweth_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcl
|
|||
static void ddsi_raweth_release_conn (ddsi_tran_conn_t conn)
|
||||
{
|
||||
ddsi_raweth_conn_t uc = (ddsi_raweth_conn_t) conn;
|
||||
DDS_INFO
|
||||
DDS_TRACE
|
||||
(
|
||||
"ddsi_raweth_release_conn %s socket %d port %d\n",
|
||||
conn->m_base.m_multicast ? "multicast" : "unicast",
|
||||
|
@ -359,7 +359,7 @@ static void ddsi_raweth_deinit(void)
|
|||
if (os_atomic_dec32_nv(&init_g) == 0) {
|
||||
if (ddsi_raweth_config_g.mship)
|
||||
free_group_membership(ddsi_raweth_config_g.mship);
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "raweth de-initialized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "raweth de-initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ int ddsi_raweth_init (void)
|
|||
|
||||
ddsi_raweth_config_g.mship = new_group_membership();
|
||||
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "raweth initialized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "raweth initialized\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -132,9 +132,9 @@ static void ddsi_tcp_cache_dump (void)
|
|||
while (n)
|
||||
{
|
||||
os_sockaddrAddressPortToString ((const os_sockaddr *) &n->m_conn->m_peer_addr, buff, sizeof (buff));
|
||||
DDS_LOG
|
||||
DDS_TRACE
|
||||
(
|
||||
DDS_LC_INFO,
|
||||
DDS_LC_TCP,
|
||||
"%s cache #%d: %s sock %d port %u peer %s\n",
|
||||
ddsi_name, i++, n->m_conn->m_base.m_server ? "server" : "client",
|
||||
n->m_conn->m_sock, n->m_conn->m_base.m_base.m_port, buff
|
||||
|
@ -169,7 +169,7 @@ static void ddsi_tcp_sock_free (os_socket sock, const char * msg)
|
|||
{
|
||||
if (msg)
|
||||
{
|
||||
DDS_INFO("%s %s free socket %"PRIsock"\n", ddsi_name, msg, sock);
|
||||
DDS_LOG(DDS_LC_TCP, "%s %s free socket %"PRIsock"\n", ddsi_name, msg, sock);
|
||||
}
|
||||
os_sockFree (sock);
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const struct msghdr * m
|
|||
#endif
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *) msg->msg_name);
|
||||
DDS_INFO("%s connect socket %"PRIsock" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s connect socket %"PRIsock" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff);
|
||||
|
||||
/* Also may need to receive on connection so add to waitset */
|
||||
|
||||
|
@ -275,7 +275,7 @@ static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ut_avlIPath_t * path)
|
|||
}
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
DDS_INFO("%s cache %s %s socket %"PRIsock" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s cache %s %s socket %"PRIsock" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
|
||||
|
@ -289,7 +289,7 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
|
|||
if (node)
|
||||
{
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
DDS_INFO("%s cache removed socket %"PRIsock" to %s\n", ddsi_name, conn->m_sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s cache removed socket %"PRIsock" to %s\n", ddsi_name, conn->m_sock, buff);
|
||||
ut_avlDeleteDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, &path);
|
||||
ddsi_tcp_node_free (node);
|
||||
}
|
||||
|
@ -643,20 +643,18 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
else
|
||||
{
|
||||
piecewise = 0;
|
||||
if (err != os_sockECONNRESET)
|
||||
switch (err)
|
||||
{
|
||||
if (! conn->m_base.m_closed && (conn->m_sock != OS_INVALID_SOCKET))
|
||||
{
|
||||
DDS_WARNING
|
||||
(
|
||||
"%s write failed on socket %"PRIsock" with errno %d\n",
|
||||
ddsi_name, conn->m_sock, err
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIsock" ECONNRESET\n", ddsi_name, conn->m_sock);
|
||||
case os_sockECONNRESET:
|
||||
#ifdef os_sockEPIPE
|
||||
case os_sockEPIPE:
|
||||
#endif
|
||||
DDS_LOG(DDS_LC_TCP, "%s write: sock %"PRIsock" ECONNRESET\n", ddsi_name, conn->m_sock);
|
||||
break;
|
||||
default:
|
||||
if (! conn->m_base.m_closed && (conn->m_sock != OS_INVALID_SOCKET))
|
||||
DDS_WARNING("%s write failed on socket %"PRIsock" with errno %d\n", ddsi_name, conn->m_sock, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -802,7 +800,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
|
|||
else
|
||||
{
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
DDS_INFO("%s accept new socket %"PRIsock" on socket %"PRIsock" from %s\n", ddsi_name, sock, tl->m_sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s accept new socket %"PRIsock" on socket %"PRIsock" from %s\n", ddsi_name, sock, tl->m_sock, buff);
|
||||
|
||||
os_sockSetNonBlocking (sock, true);
|
||||
tcp = ddsi_tcp_new_conn (sock, true, (os_sockaddr *)&addr);
|
||||
|
@ -910,7 +908,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
|
|||
}
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
DDS_INFO("%s create listener socket %"PRIsock" on %s\n", ddsi_name, sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s create listener socket %"PRIsock" on %s\n", ddsi_name, sock, buff);
|
||||
}
|
||||
|
||||
return tl ? &tl->m_base : NULL;
|
||||
|
@ -920,7 +918,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
|
|||
{
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
DDS_INFO("%s free %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s free %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
if (ddsi_tcp_ssl_plugin.ssl_free)
|
||||
|
@ -944,7 +942,7 @@ static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
|
|||
nn_locator_t loc;
|
||||
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
DDS_INFO("%s close %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
DDS_LOG(DDS_LC_TCP, "%s close %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
(void) shutdown (conn->m_sock, 2);
|
||||
ddsi_ipaddr_to_loc(&loc, (os_sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
loc.port = conn->m_peer_port;
|
||||
|
@ -1037,7 +1035,7 @@ static void ddsi_tcp_release_factory (void)
|
|||
(ddsi_tcp_ssl_plugin.fini) ();
|
||||
}
|
||||
#endif
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "tcp de-initialized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "tcp de-initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ static ddsi_tran_conn_t ddsi_udp_create_conn
|
|||
uc->m_base.m_write_fn = ddsi_udp_conn_write;
|
||||
uc->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
|
||||
|
||||
DDS_INFO
|
||||
DDS_TRACE
|
||||
(
|
||||
"ddsi_udp_create_conn %s socket %"PRIsock" port %u\n",
|
||||
mcast ? "multicast" : "unicast",
|
||||
|
@ -396,7 +396,7 @@ static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc,
|
|||
static void ddsi_udp_release_conn (ddsi_tran_conn_t conn)
|
||||
{
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
|
||||
DDS_INFO
|
||||
DDS_TRACE
|
||||
(
|
||||
"ddsi_udp_release_conn %s socket %"PRIsock" port %u\n",
|
||||
conn->m_base.m_multicast ? "multicast" : "unicast",
|
||||
|
@ -415,7 +415,7 @@ void ddsi_udp_fini (void)
|
|||
if(os_atomic_dec32_nv (&ddsi_udp_init_g) == 0) {
|
||||
free_group_membership(ddsi_udp_config_g.mship);
|
||||
memset (&ddsi_udp_factory_g, 0, sizeof (ddsi_udp_factory_g));
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "udp finalized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "udp finalized\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,7 +505,7 @@ static void ddsi_udp_deinit(void)
|
|||
if (os_atomic_dec32_nv(&ddsi_udp_init_g) == 0) {
|
||||
if (ddsi_udp_config_g.mship)
|
||||
free_group_membership(ddsi_udp_config_g.mship);
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "udp de-initialized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "udp de-initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ int ddsi_udp_init (void)
|
|||
|
||||
ddsi_factory_add (&ddsi_udp_factory_g);
|
||||
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "udp initialized\n");
|
||||
DDS_LOG(DDS_LC_CONFIG, "udp initialized\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2851,7 +2851,7 @@ struct cfgst * config_init
|
|||
case Q_CIPHER_NULL:
|
||||
/* nop */
|
||||
if ( s->key && strlen(s->key) > 0 ) {
|
||||
DDS_ERROR("config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n", s->key);
|
||||
DDS_INFO("config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n", s->key);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -538,7 +538,7 @@ static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t time
|
|||
NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER)) &&
|
||||
config.assume_rti_has_pmd_endpoints)
|
||||
{
|
||||
DDS_WARNING("data (SPDP, vendor %u.%u): assuming unadvertised PMD endpoints do exist\n",
|
||||
DDS_LOG(DDS_LC_DISCOVERY, "data (SPDP, vendor %u.%u): assuming unadvertised PMD endpoints do exist\n",
|
||||
rst->vendor.id[0], rst->vendor.id[1]);
|
||||
builtin_endpoint_set |=
|
||||
NN_BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER |
|
||||
|
@ -1837,9 +1837,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
|
|||
pid = PID_ENDPOINT_GUID;
|
||||
break;
|
||||
default:
|
||||
DDS_WARNING("data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": mapping keyhash to ENDPOINT_GUID",
|
||||
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
|
||||
PGUID (srcguid), sampleinfo->seq);
|
||||
DDS_LOG(DDS_LC_DISCOVERY, "data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": mapping keyhash to ENDPOINT_GUID",
|
||||
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
|
||||
PGUID (srcguid), sampleinfo->seq);
|
||||
pid = PID_ENDPOINT_GUID;
|
||||
break;
|
||||
}
|
||||
|
@ -1882,9 +1882,9 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str
|
|||
handle_SEDP_GROUP (sampleinfo->rst, timestamp, statusinfo, datap, datasz);
|
||||
break;
|
||||
default:
|
||||
DDS_WARNING ("data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": not handled\n",
|
||||
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
|
||||
PGUID (srcguid), sampleinfo->seq);
|
||||
DDS_LOG (DDS_LC_DISCOVERY, "data(builtin, vendor %u.%u): %x:%x:%x:%x #%"PRId64": not handled\n",
|
||||
sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1],
|
||||
PGUID (srcguid), sampleinfo->seq);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -2753,7 +2753,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
|
|||
if (wr->xqos->liveliness.kind != NN_AUTOMATIC_LIVELINESS_QOS ||
|
||||
nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration) != T_NEVER)
|
||||
{
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_DISCOVERY, "writer %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PRId64")\n", PGUID (wr->e.guid), (int) wr->xqos->liveliness.kind, nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration));
|
||||
DDS_LOG(DDS_LC_DISCOVERY, "writer %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PRId64")\n", PGUID (wr->e.guid), (int) wr->xqos->liveliness.kind, nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration));
|
||||
}
|
||||
wr->lease_duration = T_NEVER; /* FIXME */
|
||||
|
||||
|
@ -3237,7 +3237,7 @@ static struct reader * new_reader_guid
|
|||
if (rd->xqos->liveliness.kind != NN_AUTOMATIC_LIVELINESS_QOS ||
|
||||
nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration) != T_NEVER)
|
||||
{
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_DISCOVERY, "reader %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PRId64")\n", PGUID (rd->e.guid), (int) rd->xqos->liveliness.kind, nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration));
|
||||
DDS_LOG(DDS_LC_DISCOVERY, "reader %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PRId64")\n", PGUID (rd->e.guid), (int) rd->xqos->liveliness.kind, nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration));
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
|
|
|
@ -454,7 +454,6 @@ int rtps_config_open (void)
|
|||
}
|
||||
|
||||
dds_set_log_mask(config.enabled_logcats);
|
||||
dds_set_log_file(config.tracingOutputFile);
|
||||
dds_set_trace_file(config.tracingOutputFile);
|
||||
|
||||
return status;
|
||||
|
@ -487,7 +486,7 @@ int rtps_config_prep (struct cfgst *cfgst)
|
|||
inherited by readers/writers), but in many sockets mode each
|
||||
participant has its own socket, and therefore unique address
|
||||
set */
|
||||
DDS_ERROR("Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
|
||||
DDS_ERROR ("Minimal built-in endpoint set mode and ManySocketsMode are incompatible\n");
|
||||
goto err_config_late_error;
|
||||
}
|
||||
|
||||
|
@ -513,11 +512,11 @@ int rtps_config_prep (struct cfgst *cfgst)
|
|||
{
|
||||
double max = (double) config.auxiliary_bandwidth_limit * ((double) config.nack_delay / 1e9);
|
||||
if (max < 0)
|
||||
DDS_FATAL("AuxiliaryBandwidthLimit * NackDelay = %g bytes is insane\n", max);
|
||||
if (max > 2147483647.0)
|
||||
config.max_queued_rexmit_bytes = 2147483647u;
|
||||
else
|
||||
config.max_queued_rexmit_bytes = (unsigned) max;
|
||||
{
|
||||
DDS_ERROR ("AuxiliaryBandwidthLimit * NackDelay = %g bytes is insane\n", max);
|
||||
goto err_config_late_error;
|
||||
}
|
||||
config.max_queued_rexmit_bytes = max > 2147483647.0 ? 2147483647u : (unsigned) max;
|
||||
}
|
||||
#else
|
||||
config.max_queued_rexmit_bytes = 2147483647u;
|
||||
|
@ -527,7 +526,7 @@ int rtps_config_prep (struct cfgst *cfgst)
|
|||
/* Verify thread properties refer to defined threads */
|
||||
if (!check_thread_properties ())
|
||||
{
|
||||
DDS_ERROR("Could not initialise configuration\n");
|
||||
DDS_TRACE ("Could not initialise configuration\n");
|
||||
goto err_config_late_error;
|
||||
}
|
||||
|
||||
|
@ -551,8 +550,7 @@ int rtps_config_prep (struct cfgst *cfgst)
|
|||
|
||||
if (config.transport_selector != TRANS_UDP && chptr->diffserv_field != 0)
|
||||
{
|
||||
DDS_ERROR("channel %s specifies IPv4 DiffServ settings which is incompatible with IPv6 use\n",
|
||||
chptr->name);
|
||||
DDS_ERROR ("channel %s specifies IPv4 DiffServ settings which is incompatible with IPv6 use\n", chptr->name);
|
||||
error = 1;
|
||||
}
|
||||
|
||||
|
@ -575,7 +573,7 @@ int rtps_config_prep (struct cfgst *cfgst)
|
|||
printed */
|
||||
if (! rtps_config_open ())
|
||||
{
|
||||
DDS_ERROR("Could not initialise configuration\n");
|
||||
DDS_TRACE ("Could not initialise configuration\n");
|
||||
goto err_config_late_error;
|
||||
}
|
||||
|
||||
|
@ -891,7 +889,7 @@ int rtps_init (void)
|
|||
tv.tv_sec = sec;
|
||||
tv.tv_nsec = usec * 1000;
|
||||
os_ctime_r (&tv, str, sizeof(str));
|
||||
DDS_LOG(DDS_LC_INFO | DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
|
||||
DDS_LOG(DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str);
|
||||
}
|
||||
|
||||
/* Initialize thread pool */
|
||||
|
@ -940,7 +938,8 @@ int rtps_init (void)
|
|||
|
||||
if (!find_own_ip (config.networkAddressString))
|
||||
{
|
||||
DDS_ERROR("No network interface selected\n");
|
||||
/* find_own_ip already logs a more informative error message */
|
||||
DDS_LOG(DDS_LC_CONFIG, "No network interface selected\n");
|
||||
goto err_find_own_ip;
|
||||
}
|
||||
if (config.allowMulticast)
|
||||
|
|
|
@ -1866,9 +1866,8 @@ static int do_guid (nn_guid_t *dst, uint64_t *present, uint64_t fl, int (*valid)
|
|||
if (fl == PP_PARTICIPANT_GUID && vendor_is_twinoaks (dd->vendorid) &&
|
||||
dst->entityid.u == 0 && ! NN_STRICT_P)
|
||||
{
|
||||
DDS_WARNING("plist(vendor %u.%u): rewriting invalid participant guid %x:%x:%x:%x\n",
|
||||
dd->vendorid.id[0], dd->vendorid.id[1],
|
||||
dst->prefix.u[0], dst->prefix.u[1], dst->prefix.u[2], dst->entityid.u);
|
||||
DDS_LOG(DDS_LC_DISCOVERY, "plist(vendor %u.%u): rewriting invalid participant guid %x:%x:%x:%x\n",
|
||||
dd->vendorid.id[0], dd->vendorid.id[1], PGUID (*dst));
|
||||
dst->entityid.u = NN_ENTITYID_PARTICIPANT;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -799,18 +799,9 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
|||
nn_wctime_t tstamp_now = now ();
|
||||
nn_wctime_t tstamp_msg = nn_wctime_from_ddsi_time (timestamp);
|
||||
nn_lat_estim_update (&rn->hb_to_ack_latency, tstamp_now.v - tstamp_msg.v);
|
||||
if ((dds_get_log_mask() & (DDS_LC_TRACE | DDS_LC_INFO)) &&
|
||||
tstamp_now.v > rn->hb_to_ack_latency_tlastlog.v + 10 * T_SECOND)
|
||||
if ((dds_get_log_mask() & DDS_LC_TRACE) && tstamp_now.v > rn->hb_to_ack_latency_tlastlog.v + 10 * T_SECOND)
|
||||
{
|
||||
if (dds_get_log_mask() & DDS_LC_TRACE)
|
||||
nn_lat_estim_log (DDS_LC_TRACE, NULL, &rn->hb_to_ack_latency);
|
||||
else if (dds_get_log_mask() & DDS_LC_INFO)
|
||||
{
|
||||
char tagbuf[2*(4*8+3) + 4 + 1];
|
||||
(void) snprintf (tagbuf, sizeof (tagbuf), "%x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst));
|
||||
if (nn_lat_estim_log (DDS_LC_INFO, tagbuf, &rn->hb_to_ack_latency))
|
||||
DDS_LOG(DDS_LC_INFO, "\n");
|
||||
}
|
||||
nn_lat_estim_log (DDS_LC_TRACE, NULL, &rn->hb_to_ack_latency);
|
||||
rn->hb_to_ack_latency_tlastlog = tstamp_now;
|
||||
}
|
||||
}
|
||||
|
@ -856,7 +847,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
|
|||
rn->seq = wr->seq;
|
||||
}
|
||||
ut_avlAugmentUpdate (&wr_readers_treedef, rn);
|
||||
DDS_WARNING("writer %x:%x:%x:%x considering reader %x:%x:%x:%x responsive again\n", PGUID (wr->e.guid), PGUID (rn->prd_guid));
|
||||
DDS_LOG(DDS_LC_THROTTLE, "writer %x:%x:%x:%x considering reader %x:%x:%x:%x responsive again\n", PGUID (wr->e.guid), PGUID (rn->prd_guid));
|
||||
}
|
||||
|
||||
/* Second, the NACK bits (literally, that is). To do so, attempt to
|
||||
|
|
|
@ -116,7 +116,7 @@ static uint32_t lease_renewal_thread (struct nn_servicelease *sl)
|
|||
msg = "failed to make progress";
|
||||
else
|
||||
msg = "once again made progress";
|
||||
DDS_WARNING("thread %s %s\n", name ? name : "(anon)", msg);
|
||||
DDS_INFO("thread %s %s\n", name ? name : "(anon)", msg);
|
||||
sl->av_ary[i].alive = (char) alive;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ lookup_thread_state(
|
|||
os_osInit();
|
||||
ts1->extTid = tid;
|
||||
ts1->tid = tid;
|
||||
DDS_LOG(DDS_LC_INFO, "started application thread %s\n", tname);
|
||||
DDS_LOG(DDS_LC_TRACE, "started application thread %s\n", tname);
|
||||
os_threadCleanupPush(&cleanup_thread_state, NULL);
|
||||
}
|
||||
os_mutexUnlock(&thread_states.lock);
|
||||
|
@ -275,7 +275,7 @@ struct thread_state1 *create_thread (_In_z_ const char *name, _In_ uint32_t (*f)
|
|||
DDS_FATAL("create_thread: %s: os_threadCreate failed\n", name);
|
||||
goto fatal;
|
||||
}
|
||||
DDS_LOG(DDS_LC_INFO, "started new thread 0x%"PRIxMAX" : %s\n", os_threadIdToInteger (tid), name);
|
||||
DDS_LOG(DDS_LC_TRACE, "started new thread 0x%"PRIxMAX" : %s\n", os_threadIdToInteger (tid), name);
|
||||
ts1->extTid = tid; /* overwrite the temporary value with the correct external one */
|
||||
os_mutexUnlock (&thread_states.lock);
|
||||
return ts1;
|
||||
|
|
|
@ -64,6 +64,7 @@ extern "C" {
|
|||
#define os_sockENETUNREACH ENETUNREACH /* Network is unreachable */
|
||||
#define os_sockENOBUFS ENOBUFS /* No buffer space available */
|
||||
#define os_sockECONNRESET ECONNRESET /* Connection reset by peer */
|
||||
#define os_sockEPIPE EPIPE /* Connection reset by peer */
|
||||
|
||||
typedef int os_socket; /* signed */
|
||||
#define PRIsock "d"
|
||||
|
|
|
@ -146,6 +146,7 @@ void dds_set_log_file(_In_ FILE *file)
|
|||
if (sinks[LOG].funcs[SET] == default_sink) {
|
||||
sinks[LOG].ptr = sinks[LOG].out;
|
||||
}
|
||||
set_active_log_sinks();
|
||||
unlock_sink();
|
||||
}
|
||||
|
||||
|
@ -156,6 +157,7 @@ void dds_set_trace_file(_In_ FILE *file)
|
|||
if (sinks[TRACE].funcs[SET] == default_sink) {
|
||||
sinks[TRACE].ptr = sinks[TRACE].out;
|
||||
}
|
||||
set_active_log_sinks();
|
||||
unlock_sink();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,13 +32,15 @@
|
|||
#include <limits.h>
|
||||
|
||||
typedef struct {
|
||||
char *threadName;
|
||||
void *arguments;
|
||||
uint32_t (*startRoutine)(void *);
|
||||
char *threadName;
|
||||
void *arguments;
|
||||
uint32_t (*startRoutine) (void *);
|
||||
} os_threadContext;
|
||||
|
||||
static pthread_key_t os_threadNameKey;
|
||||
static pthread_key_t os_threadMemKey;
|
||||
static pthread_key_t cleanup_key;
|
||||
static pthread_once_t cleanup_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static sigset_t os_threadBlockAllMask;
|
||||
|
||||
|
@ -55,23 +57,16 @@ static sigset_t os_threadBlockAllMask;
|
|||
* or
|
||||
* an appropriate error report is generated
|
||||
*/
|
||||
static void
|
||||
os_threadMemInit (
|
||||
void)
|
||||
static void os_threadMemInit (void)
|
||||
{
|
||||
void *pthreadMemArray;
|
||||
|
||||
pthreadMemArray = os_malloc (sizeof(void *) * OS_THREAD_MEM_ARRAY_SIZE);
|
||||
if (pthreadMemArray != NULL) {
|
||||
memset (pthreadMemArray, 0, sizeof(void *) * OS_THREAD_MEM_ARRAY_SIZE);
|
||||
if (pthread_setspecific (os_threadMemKey, pthreadMemArray) == EINVAL) {
|
||||
DDS_ERROR("pthread_setspecific failed with error EINVAL (%d), "
|
||||
"invalid threadMemKey value\n", EINVAL);
|
||||
os_free(pthreadMemArray);
|
||||
}
|
||||
} else {
|
||||
DDS_ERROR("Out of heap memory\n");
|
||||
}
|
||||
const size_t sz = sizeof(void *) * OS_THREAD_MEM_ARRAY_SIZE;
|
||||
void *pthreadMemArray;
|
||||
int ret;
|
||||
if ((pthreadMemArray = os_malloc (sz)) == NULL)
|
||||
DDS_FATAL ("os_threadMemInit: out of memory\n");
|
||||
memset (pthreadMemArray, 0, sz);
|
||||
if ((ret = pthread_setspecific (os_threadMemKey, pthreadMemArray)) != 0)
|
||||
DDS_FATAL ("pthread_setspecific failed with error (%d), invalid threadMemKey value\n", ret);
|
||||
}
|
||||
|
||||
/** \brief Initialize the thread private memory array
|
||||
|
@ -88,26 +83,19 @@ os_threadMemInit (
|
|||
* or
|
||||
* an appropriate error report is generated
|
||||
*/
|
||||
static void
|
||||
os_threadMemExit(
|
||||
void)
|
||||
static void os_threadMemExit (void)
|
||||
{
|
||||
void **pthreadMemArray;
|
||||
int32_t i;
|
||||
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray != NULL) {
|
||||
for (i = 0; i < OS_THREAD_MEM_ARRAY_SIZE; i++) {
|
||||
if (pthreadMemArray[i] != NULL) {
|
||||
os_free (pthreadMemArray[i]);
|
||||
}
|
||||
}
|
||||
os_free (pthreadMemArray);
|
||||
pthreadMemArray = NULL;
|
||||
if (pthread_setspecific (os_threadMemKey, pthreadMemArray) == EINVAL) {
|
||||
DDS_ERROR("pthread_setspecific failed with error %d\n", EINVAL);
|
||||
}
|
||||
}
|
||||
void **pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray != NULL)
|
||||
{
|
||||
int ret;
|
||||
for (int i = 0; i < OS_THREAD_MEM_ARRAY_SIZE; i++)
|
||||
if (pthreadMemArray[i] != NULL)
|
||||
os_free (pthreadMemArray[i]);
|
||||
os_free (pthreadMemArray);
|
||||
if ((ret = pthread_setspecific (os_threadMemKey, NULL)) != 0)
|
||||
DDS_FATAL ("pthread_setspecific failed with error %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Initialize the thread module
|
||||
|
@ -115,16 +103,12 @@ os_threadMemExit(
|
|||
* \b os_threadModuleInit initializes the thread module for the
|
||||
* calling process
|
||||
*/
|
||||
void
|
||||
os_threadModuleInit (
|
||||
void)
|
||||
void os_threadModuleInit (void)
|
||||
{
|
||||
pthread_key_create (&os_threadNameKey, NULL);
|
||||
pthread_key_create (&os_threadMemKey, NULL);
|
||||
|
||||
sigfillset(&os_threadBlockAllMask);
|
||||
|
||||
os_threadMemInit();
|
||||
pthread_key_create (&os_threadNameKey, NULL);
|
||||
pthread_key_create (&os_threadMemKey, NULL);
|
||||
sigfillset(&os_threadBlockAllMask);
|
||||
os_threadMemInit();
|
||||
}
|
||||
|
||||
/** \brief Deinitialize the thread module
|
||||
|
@ -132,13 +116,11 @@ os_threadModuleInit (
|
|||
* \b os_threadModuleExit deinitializes the thread module for the
|
||||
* calling process
|
||||
*/
|
||||
void
|
||||
os_threadModuleExit(void)
|
||||
void os_threadModuleExit (void)
|
||||
{
|
||||
os_threadMemExit();
|
||||
|
||||
pthread_key_delete(os_threadNameKey);
|
||||
pthread_key_delete(os_threadMemKey);
|
||||
os_threadMemExit();
|
||||
pthread_key_delete(os_threadNameKey);
|
||||
pthread_key_delete(os_threadMemKey);
|
||||
}
|
||||
|
||||
/** \brief Wrap thread start routine
|
||||
|
@ -148,43 +130,40 @@ os_threadModuleExit(void)
|
|||
* in the context of the thread. With \b pthread_getspecific,
|
||||
* the name can be retreived for different purposes.
|
||||
*/
|
||||
static void *
|
||||
os_startRoutineWrapper (
|
||||
void *threadContext)
|
||||
static void *os_startRoutineWrapper (void *threadContext)
|
||||
{
|
||||
os_threadContext *context = threadContext;
|
||||
uintptr_t resultValue;
|
||||
os_threadContext *context = threadContext;
|
||||
uintptr_t resultValue;
|
||||
int ret;
|
||||
|
||||
#if !defined(__VXWORKS__) && !defined(__APPLE__) && !defined(__sun)
|
||||
/* FIXME: Switch to use pthread_setname_np in the future.
|
||||
* Linux: pthread_setname_np(pthread_t, const char *)
|
||||
* macOS: pthread_setname_np(const char *)
|
||||
* FreeBSD: pthread_set_name_np(pthread_t, const char *) */
|
||||
prctl(PR_SET_NAME, context->threadName);
|
||||
/* FIXME: Switch to use pthread_setname_np in the future.
|
||||
* Linux: pthread_setname_np(pthread_t, const char *)
|
||||
* macOS: pthread_setname_np(const char *)
|
||||
* FreeBSD: pthread_set_name_np(pthread_t, const char *) */
|
||||
prctl(PR_SET_NAME, context->threadName);
|
||||
#endif
|
||||
|
||||
/* store the thread name with the thread via thread specific data; failure isn't */
|
||||
if (pthread_setspecific (os_threadNameKey, context->threadName) == EINVAL) {
|
||||
DDS_WARNING("pthread_setspecific failed with error EINVAL (%d), "
|
||||
"invalid os_threadNameKey value\n", EINVAL);
|
||||
}
|
||||
/* store the thread name with the thread via thread specific data */
|
||||
if ((ret = pthread_setspecific (os_threadNameKey, context->threadName)) != 0)
|
||||
DDS_FATAL ("pthread_setspecific failed with error %d, invalid os_threadNameKey value\n", ret);
|
||||
|
||||
/* allocate an array to store thread private memory references */
|
||||
os_threadMemInit ();
|
||||
/* allocate an array to store thread private memory references */
|
||||
os_threadMemInit ();
|
||||
|
||||
/* Call the user routine */
|
||||
resultValue = context->startRoutine (context->arguments);
|
||||
/* Call the user routine */
|
||||
resultValue = context->startRoutine (context->arguments);
|
||||
|
||||
/* Free the thread context resources, arguments is responsibility */
|
||||
/* for the caller of os_procCreate */
|
||||
os_free(context->threadName);
|
||||
os_free(context);
|
||||
/* Free the thread context resources, arguments is responsibility */
|
||||
/* for the caller of os_procCreate */
|
||||
os_free (context->threadName);
|
||||
os_free (context);
|
||||
|
||||
/* deallocate the array to store thread private memory references */
|
||||
os_threadMemExit ();
|
||||
/* deallocate the array to store thread private memory references */
|
||||
os_threadMemExit ();
|
||||
|
||||
/* return the result of the user routine */
|
||||
return (void *)resultValue;
|
||||
/* return the result of the user routine */
|
||||
return (void *)resultValue;
|
||||
}
|
||||
|
||||
/** \brief Create a new thread
|
||||
|
@ -200,162 +179,113 @@ os_startRoutineWrapper (
|
|||
* is needed to be able to wait for the threads termination
|
||||
* in \b os_threadWaitExit.
|
||||
*/
|
||||
os_result
|
||||
os_threadCreate (
|
||||
os_threadId *threadId,
|
||||
const char *name,
|
||||
const os_threadAttr *threadAttr,
|
||||
uint32_t (* start_routine)(void *),
|
||||
void *arg)
|
||||
os_result os_threadCreate (os_threadId *threadId, const char *name, const os_threadAttr *threadAttr, uint32_t (*start_routine) (void *), void *arg)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
struct sched_param sched_param;
|
||||
os_result rv = os_resultSuccess;
|
||||
os_threadContext *threadContext;
|
||||
os_threadAttr tattr;
|
||||
int result, create_ret;
|
||||
int policy;
|
||||
pthread_attr_t attr;
|
||||
os_threadContext *threadContext;
|
||||
os_threadAttr tattr;
|
||||
int result, create_ret;
|
||||
|
||||
assert (threadId != NULL);
|
||||
assert (name != NULL);
|
||||
assert (threadAttr != NULL);
|
||||
assert (start_routine != NULL);
|
||||
tattr = *threadAttr;
|
||||
assert (threadId != NULL);
|
||||
assert (name != NULL);
|
||||
assert (threadAttr != NULL);
|
||||
assert (start_routine != NULL);
|
||||
tattr = *threadAttr;
|
||||
|
||||
if (pthread_attr_init (&attr) != 0)
|
||||
return os_resultFail;
|
||||
|
||||
if (tattr.schedClass == OS_SCHED_DEFAULT) {
|
||||
#if 0 /* FIXME! */
|
||||
tattr.schedClass = os_procAttrGetClass ();
|
||||
tattr.schedPriority = os_procAttrGetPriority ();
|
||||
#endif
|
||||
}
|
||||
if (pthread_attr_init (&attr) != 0)
|
||||
{
|
||||
rv = os_resultFail;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __VXWORKS__
|
||||
/* PR_SET_NAME is not available on VxWorks. Use pthread_attr_setname
|
||||
instead (proprietary VxWorks extension) */
|
||||
(void)pthread_attr_setname(&attr, name);
|
||||
/* PR_SET_NAME is not available on VxWorks. Use pthread_attr_setname instead (proprietary VxWorks extension) */
|
||||
(void) pthread_attr_setname (&attr, name);
|
||||
#endif
|
||||
if (pthread_getschedparam(pthread_self(), &policy, &sched_param) != 0 ||
|
||||
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM) != 0 ||
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE) != 0 ||
|
||||
pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED) != 0)
|
||||
{
|
||||
rv = os_resultFail;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tattr.stackSize != 0) {
|
||||
|
||||
if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM) != 0 ||
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE) != 0)
|
||||
goto err;
|
||||
|
||||
if (tattr.stackSize != 0)
|
||||
{
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
if ( tattr.stackSize < PTHREAD_STACK_MIN ) {
|
||||
tattr.stackSize = PTHREAD_STACK_MIN;
|
||||
}
|
||||
if (tattr.stackSize < PTHREAD_STACK_MIN)
|
||||
tattr.stackSize = PTHREAD_STACK_MIN;
|
||||
#endif
|
||||
if (pthread_attr_setstacksize (&attr, tattr.stackSize) != 0) {
|
||||
rv = os_resultFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == os_resultSuccess) {
|
||||
if (tattr.schedClass == OS_SCHED_REALTIME) {
|
||||
result = pthread_attr_setschedpolicy (&attr, SCHED_FIFO);
|
||||
|
||||
if (result != 0) {
|
||||
char errmsg[64];
|
||||
(void)os_strerror_r(result, errmsg, sizeof(errmsg));
|
||||
DDS_WARNING("pthread_attr_setschedpolicy failed for SCHED_FIFO with "
|
||||
"error %d (%s) for thread '%s', reverting to SCHED_OTHER\n",
|
||||
result, errmsg, name);
|
||||
|
||||
result = pthread_attr_setschedpolicy (&attr, SCHED_OTHER);
|
||||
if (result != 0) {
|
||||
DDS_WARNING("pthread_attr_setschedpolicy failed with error %d (%s)\n", result, name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = pthread_attr_setschedpolicy (&attr, SCHED_OTHER);
|
||||
|
||||
if (result != 0) {
|
||||
DDS_WARNING("pthread_attr_setschedpolicy failed with error %d (%s)\n", result, name);
|
||||
}
|
||||
}
|
||||
pthread_attr_getschedpolicy(&attr, &policy);
|
||||
|
||||
if ((tattr.schedPriority < sched_get_priority_min(policy)) ||
|
||||
(tattr.schedPriority > sched_get_priority_max(policy))) {
|
||||
DDS_WARNING("scheduling priority outside valid range for the policy "
|
||||
"reverted to valid value (%s)\n", name);
|
||||
sched_param.sched_priority = (sched_get_priority_min(policy) +
|
||||
sched_get_priority_max(policy)) / 2;
|
||||
} else {
|
||||
sched_param.sched_priority = tattr.schedPriority;
|
||||
}
|
||||
/* Take over the thread context: name, start routine and argument */
|
||||
threadContext = os_malloc (sizeof (os_threadContext));
|
||||
threadContext->threadName = os_malloc (strlen (name)+1);
|
||||
strcpy (threadContext->threadName, name);
|
||||
threadContext->startRoutine = start_routine;
|
||||
threadContext->arguments = arg;
|
||||
|
||||
/* start the thread */
|
||||
result = pthread_attr_setschedparam (&attr, &sched_param);
|
||||
if (result != 0) {
|
||||
DDS_WARNING("pthread_attr_setschedparam failed with error %d (%s)\n",
|
||||
result, name);
|
||||
}
|
||||
|
||||
create_ret = pthread_create(&threadId->v, &attr, os_startRoutineWrapper,
|
||||
threadContext);
|
||||
if (create_ret != 0) {
|
||||
/* In case real-time thread creation failed due to a lack
|
||||
* of permissions, try reverting to time-sharing and continue.
|
||||
*/
|
||||
if((create_ret == EPERM) && (tattr.schedClass == OS_SCHED_REALTIME))
|
||||
{
|
||||
DDS_WARNING("pthread_create failed with SCHED_FIFO "
|
||||
"for thread '%s', reverting to SCHED_OTHER\n",
|
||||
name);
|
||||
(void) pthread_attr_setschedpolicy (&attr, SCHED_OTHER); /* SCHED_OTHER is always supported */
|
||||
pthread_attr_getschedpolicy(&attr, &policy);
|
||||
|
||||
if ((tattr.schedPriority < sched_get_priority_min(policy)) ||
|
||||
(tattr.schedPriority > sched_get_priority_max(policy)))
|
||||
{
|
||||
DDS_WARNING("scheduling priority outside valid range for the "
|
||||
"policy reverted to valid value (%s)\n", name);
|
||||
sched_param.sched_priority =
|
||||
(sched_get_priority_min(policy) +
|
||||
sched_get_priority_max(policy)) / 2;
|
||||
} else {
|
||||
sched_param.sched_priority = tattr.schedPriority;
|
||||
}
|
||||
|
||||
result = pthread_attr_setschedparam (&attr, &sched_param);
|
||||
if (result != 0) {
|
||||
DDS_WARNING("pthread_attr_setschedparam failed "
|
||||
"with error %d (%s)", result, name);
|
||||
} else {
|
||||
create_ret = pthread_create(&threadId->v, &attr,
|
||||
os_startRoutineWrapper, threadContext);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rv = os_resultSuccess;
|
||||
}
|
||||
if(create_ret != 0){
|
||||
os_free (threadContext->threadName);
|
||||
os_free (threadContext);
|
||||
DDS_WARNING("pthread_create failed with error %d (%s)\n", create_ret, name);
|
||||
rv = os_resultFail;
|
||||
}
|
||||
}
|
||||
pthread_attr_destroy (&attr);
|
||||
if ((result = pthread_attr_setstacksize (&attr, tattr.stackSize)) != 0)
|
||||
{
|
||||
DDS_ERROR ("os_threadCreate(%s): pthread_attr_setstacksize(%"PRIu32") failed with error %d\n", name, tattr.stackSize, result);
|
||||
goto err;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (tattr.schedClass == OS_SCHED_DEFAULT)
|
||||
{
|
||||
if (tattr.schedPriority != 0)
|
||||
{
|
||||
/* If caller doesn't set the class, he must not try to set the priority, which we
|
||||
approximate by expecting a 0. FIXME: should do this as part of config validation */
|
||||
DDS_ERROR("os_threadCreate(%s): schedClass DEFAULT but priority != 0 is unsupported\n", name);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
if ((result = pthread_getschedparam (pthread_self (), &policy, &sched_param) != 0) != 0)
|
||||
{
|
||||
DDS_ERROR("os_threadCreate(%s): pthread_attr_getschedparam(self) failed with error %d\n", name, result);
|
||||
goto err;
|
||||
}
|
||||
switch (tattr.schedClass)
|
||||
{
|
||||
case OS_SCHED_DEFAULT:
|
||||
assert (0);
|
||||
break;
|
||||
case OS_SCHED_REALTIME:
|
||||
policy = SCHED_FIFO;
|
||||
break;
|
||||
case OS_SCHED_TIMESHARE:
|
||||
policy = SCHED_OTHER;
|
||||
break;
|
||||
}
|
||||
if ((result = pthread_attr_setschedpolicy (&attr, policy)) != 0)
|
||||
{
|
||||
DDS_ERROR("os_threadCreate(%s): pthread_attr_setschedpolicy(%d) failed with error %d\n", name, policy, result);
|
||||
goto err;
|
||||
}
|
||||
sched_param.sched_priority = tattr.schedPriority;
|
||||
if ((result = pthread_attr_setschedparam (&attr, &sched_param)) != 0)
|
||||
{
|
||||
DDS_ERROR("os_threadCreate(%s): pthread_attr_setschedparam(priority = %d) failed with error %d\n", name, tattr.schedPriority, result);
|
||||
goto err;
|
||||
}
|
||||
if ((result = pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED)) != 0)
|
||||
{
|
||||
DDS_ERROR("os_threadCreate(%s): pthread_attr_setinheritsched(EXPLICIT) failed with error %d\n", name, result);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct context structure & start thread */
|
||||
threadContext = os_malloc (sizeof (os_threadContext));
|
||||
threadContext->threadName = os_malloc (strlen (name) + 1);
|
||||
strcpy (threadContext->threadName, name);
|
||||
threadContext->startRoutine = start_routine;
|
||||
threadContext->arguments = arg;
|
||||
if ((create_ret = pthread_create (&threadId->v, &attr, os_startRoutineWrapper, threadContext)) != 0)
|
||||
{
|
||||
DDS_ERROR ("os_threadCreate(%s): pthread_create failed with error %d\n", name, create_ret);
|
||||
goto err_create;
|
||||
}
|
||||
pthread_attr_destroy (&attr);
|
||||
return os_resultSuccess;
|
||||
|
||||
err_create:
|
||||
os_free (threadContext->threadName);
|
||||
os_free (threadContext);
|
||||
err:
|
||||
pthread_attr_destroy (&attr);
|
||||
return os_resultFail;
|
||||
}
|
||||
|
||||
/** \brief Return the integer representation of the given thread ID
|
||||
|
@ -363,10 +293,9 @@ os_threadCreate (
|
|||
* Possible Results:
|
||||
* - returns the integer representation of the given thread ID
|
||||
*/
|
||||
uintmax_t
|
||||
os_threadIdToInteger(os_threadId id)
|
||||
uintmax_t os_threadIdToInteger (os_threadId id)
|
||||
{
|
||||
return (uintmax_t)(uintptr_t)id.v;
|
||||
return (uintmax_t) ((uintptr_t) id.v);
|
||||
}
|
||||
|
||||
/** \brief Return the thread ID of the calling thread
|
||||
|
@ -374,27 +303,18 @@ os_threadIdToInteger(os_threadId id)
|
|||
* \b os_threadIdSelf determines the own thread ID by
|
||||
* calling \b pthread_self.
|
||||
*/
|
||||
os_threadId
|
||||
os_threadIdSelf (void)
|
||||
os_threadId os_threadIdSelf (void)
|
||||
{
|
||||
os_threadId id = {.v = pthread_self ()};
|
||||
return id;
|
||||
os_threadId id = { .v = pthread_self () };
|
||||
return id;
|
||||
}
|
||||
|
||||
int32_t
|
||||
os_threadGetThreadName (
|
||||
char *buffer,
|
||||
uint32_t length)
|
||||
int32_t os_threadGetThreadName (char *buffer, uint32_t length)
|
||||
{
|
||||
char *name;
|
||||
|
||||
assert (buffer != NULL);
|
||||
|
||||
if ((name = pthread_getspecific (os_threadNameKey)) == NULL) {
|
||||
name = "";
|
||||
}
|
||||
|
||||
return snprintf (buffer, length, "%s", name);
|
||||
char *name;
|
||||
if ((name = pthread_getspecific (os_threadNameKey)) == NULL)
|
||||
name = "";
|
||||
return snprintf (buffer, length, "%s", name);
|
||||
}
|
||||
|
||||
/** \brief Wait for the termination of the identified thread
|
||||
|
@ -403,59 +323,50 @@ os_threadGetThreadName (
|
|||
* thread \b threadId by calling \b pthread_join. The return
|
||||
* value of the thread is passed via \b thread_result.
|
||||
*/
|
||||
os_result
|
||||
os_threadWaitExit (
|
||||
os_threadId threadId,
|
||||
uint32_t *thread_result)
|
||||
os_result os_threadWaitExit (os_threadId threadId, uint32_t *thread_result)
|
||||
{
|
||||
os_result rv;
|
||||
int result;
|
||||
void *vthread_result;
|
||||
int result;
|
||||
void *vthread_result;
|
||||
|
||||
assert (threadId.v);
|
||||
assert (threadId.v);
|
||||
|
||||
#if defined(__VXWORKS__) && !defined(_WRS_KERNEL)
|
||||
struct sched_param sched_param;
|
||||
int max, policy = 0;
|
||||
struct sched_param sched_param;
|
||||
int max, policy = 0;
|
||||
|
||||
/* There is a known issue in pthread_join on VxWorks 6.x RTP mode.
|
||||
/* There is a known issue in pthread_join on VxWorks 6.x RTP mode.
|
||||
|
||||
WindRiver: When pthread_join returns, it does not indicate end of a
|
||||
thread in 100% of the situations. If the thread that calls pthread_join
|
||||
has a higher priority than the thread that is currently terminating,
|
||||
pthread_join could return before pthread_exit has finished. This
|
||||
conflicts with the POSIX specification that dictates that pthread_join
|
||||
must only return when the thread is really terminated. The workaround
|
||||
suggested by WindRiver support is to increase the priority of the thread
|
||||
(task) to be terminated before handing back the semaphore to ensure the
|
||||
thread exits before pthread_join returns.
|
||||
WindRiver: When pthread_join returns, it does not indicate end of a
|
||||
thread in 100% of the situations. If the thread that calls pthread_join
|
||||
has a higher priority than the thread that is currently terminating,
|
||||
pthread_join could return before pthread_exit has finished. This
|
||||
conflicts with the POSIX specification that dictates that pthread_join
|
||||
must only return when the thread is really terminated. The workaround
|
||||
suggested by WindRiver support is to increase the priority of the thread
|
||||
(task) to be terminated before handing back the semaphore to ensure the
|
||||
thread exits before pthread_join returns.
|
||||
|
||||
This bug was submitted to WindRiver as TSR 815826. */
|
||||
This bug was submitted to WindRiver as TSR 815826. */
|
||||
|
||||
/* Note that any possible errors raised here are not terminal since the
|
||||
thread may have exited at this point anyway. */
|
||||
if (pthread_getschedparam(threadId.v, &policy, &sched_param) == 0) {
|
||||
max = sched_get_priority_max(policy);
|
||||
if (max != -1) {
|
||||
(void)pthread_setschedprio(threadId.v, max);
|
||||
}
|
||||
/* Note that any possible errors raised here are not terminal since the
|
||||
thread may have exited at this point anyway. */
|
||||
if (pthread_getschedparam (threadId.v, &policy, &sched_param) == 0) {
|
||||
max = sched_get_priority_max (policy);
|
||||
if (max != -1) {
|
||||
(void) pthread_setschedprio (threadId.v, max);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
result = pthread_join (threadId.v, &vthread_result);
|
||||
if (result != 0) {
|
||||
/* NOTE: The below report actually is a debug output; makes no sense from
|
||||
* a customer perspective. Made OS_INFO for now. */
|
||||
DDS_INFO("pthread_join(0x%"PRIxMAX") failed with error %d\n", os_threadIdToInteger(threadId), result);
|
||||
rv = os_resultFail;
|
||||
} else {
|
||||
rv = os_resultSuccess;
|
||||
}
|
||||
if(thread_result){
|
||||
uintptr_t res = (uintptr_t)vthread_result;
|
||||
*thread_result = (uint32_t)res;
|
||||
}
|
||||
return rv;
|
||||
if ((result = pthread_join (threadId.v, &vthread_result)) != 0)
|
||||
{
|
||||
DDS_TRACE ("pthread_join(0x%"PRIxMAX") failed with error %d\n", os_threadIdToInteger (threadId), result);
|
||||
return os_resultFail;
|
||||
}
|
||||
|
||||
if (thread_result)
|
||||
*thread_result = (uint32_t) ((uintptr_t) vthread_result);
|
||||
return os_resultSuccess;
|
||||
}
|
||||
|
||||
/** \brief Allocate thread private memory
|
||||
|
@ -478,30 +389,20 @@ os_threadWaitExit (
|
|||
* of the requested size if
|
||||
* memory is successfully allocated
|
||||
*/
|
||||
void *
|
||||
os_threadMemMalloc (
|
||||
int32_t index,
|
||||
size_t size)
|
||||
void *os_threadMemMalloc (int32_t index, size_t size)
|
||||
{
|
||||
void **pthreadMemArray;
|
||||
void *threadMemLoc = NULL;
|
||||
void **pthreadMemArray;
|
||||
|
||||
if ((0 <= index) && (index < OS_THREAD_MEM_ARRAY_SIZE)) {
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray == NULL) {
|
||||
os_threadMemInit ();
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
}
|
||||
if (pthreadMemArray != NULL) {
|
||||
if (pthreadMemArray[index] == NULL) {
|
||||
threadMemLoc = os_malloc (size);
|
||||
if (threadMemLoc != NULL) {
|
||||
pthreadMemArray[index] = threadMemLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return threadMemLoc;
|
||||
assert (0 <= index && index < OS_THREAD_MEM_ARRAY_SIZE);
|
||||
if ((pthreadMemArray = pthread_getspecific (os_threadMemKey)) == NULL)
|
||||
{
|
||||
os_threadMemInit ();
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
}
|
||||
assert (pthreadMemArray[index] == NULL);
|
||||
|
||||
pthreadMemArray[index] = os_malloc (size);
|
||||
return pthreadMemArray[index];
|
||||
}
|
||||
|
||||
/** \brief Free thread private memory
|
||||
|
@ -515,23 +416,15 @@ os_threadMemMalloc (
|
|||
* - os_threadMemGet (index) = NULL and allocated
|
||||
* heap memory is freed
|
||||
*/
|
||||
void
|
||||
os_threadMemFree (
|
||||
int32_t index)
|
||||
void os_threadMemFree (int32_t index)
|
||||
{
|
||||
void **pthreadMemArray;
|
||||
void *threadMemLoc = NULL;
|
||||
|
||||
if ((0 <= index) && (index < OS_THREAD_MEM_ARRAY_SIZE)) {
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray != NULL) {
|
||||
threadMemLoc = pthreadMemArray[index];
|
||||
if (threadMemLoc != NULL) {
|
||||
pthreadMemArray[index] = NULL;
|
||||
os_free (threadMemLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert (0 <= index && index < OS_THREAD_MEM_ARRAY_SIZE);
|
||||
void **pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray != NULL && pthreadMemArray[index] != NULL)
|
||||
{
|
||||
os_free (pthreadMemArray[index]);
|
||||
pthreadMemArray[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Get thread private memory
|
||||
|
@ -544,103 +437,76 @@ os_threadMemFree (
|
|||
* the specified index
|
||||
* - returns a reference to the allocated memory
|
||||
*/
|
||||
void *
|
||||
os_threadMemGet (
|
||||
int32_t index)
|
||||
void *os_threadMemGet (int32_t index)
|
||||
{
|
||||
void **pthreadMemArray;
|
||||
void *threadMemLoc = NULL;
|
||||
|
||||
if ((0 <= index) && (index < OS_THREAD_MEM_ARRAY_SIZE)) {
|
||||
pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
if (pthreadMemArray != NULL) {
|
||||
threadMemLoc = pthreadMemArray[index];
|
||||
}
|
||||
}
|
||||
return threadMemLoc;
|
||||
assert (0 <= index && index < OS_THREAD_MEM_ARRAY_SIZE);
|
||||
void **pthreadMemArray = pthread_getspecific (os_threadMemKey);
|
||||
return (pthreadMemArray != NULL) ? pthreadMemArray[index] : NULL;
|
||||
}
|
||||
|
||||
|
||||
static pthread_key_t cleanup_key;
|
||||
static pthread_once_t cleanup_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void
|
||||
os_threadCleanupFini(
|
||||
void *data)
|
||||
static void os_threadCleanupFini (void *data)
|
||||
{
|
||||
os_iter *itr;
|
||||
os_threadCleanup *obj;
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
if (data != NULL) {
|
||||
itr = (os_iter *)data;
|
||||
for (obj = (os_threadCleanup *)os_iterTake(itr, -1);
|
||||
obj != NULL;
|
||||
obj = (os_threadCleanup *)os_iterTake(itr, -1))
|
||||
{
|
||||
assert(obj->func != NULL);
|
||||
obj->func(obj->data);
|
||||
os_free(obj);
|
||||
}
|
||||
os_iterFree(itr, NULL);
|
||||
}
|
||||
os_iter *itr = data;
|
||||
os_threadCleanup *obj;
|
||||
for (obj = os_iterTake (itr, -1); obj != NULL; obj = os_iterTake (itr, -1))
|
||||
{
|
||||
assert (obj->func != NULL);
|
||||
obj->func (obj->data);
|
||||
os_free (obj);
|
||||
}
|
||||
os_iterFree (itr, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
os_threadCleanupInit(
|
||||
void)
|
||||
static void os_threadCleanupInit (void)
|
||||
{
|
||||
(void)pthread_key_create(&cleanup_key, &os_threadCleanupFini);
|
||||
int ret;
|
||||
if ((ret = pthread_key_create (&cleanup_key, &os_threadCleanupFini)) != 0)
|
||||
DDS_FATAL ("os_threadCleanupInit: pthread_key_create failed with error %d\n", ret);
|
||||
}
|
||||
|
||||
/* os_threadCleanupPush and os_threadCleanupPop are mapped onto a destructor
|
||||
registered with pthread_key_create in stead of being mapped directly onto
|
||||
pthread_cleanup_push/pthread_cleanup_pop because the cleanup routines could
|
||||
otherwise be popped of the stack by the user */
|
||||
void
|
||||
os_threadCleanupPush(
|
||||
void (*func)(void*),
|
||||
void *data)
|
||||
registered with pthread_key_create in stead of being mapped directly onto
|
||||
pthread_cleanup_push/pthread_cleanup_pop because the cleanup routines could
|
||||
otherwise be popped of the stack by the user */
|
||||
void os_threadCleanupPush (void (*func) (void *), void *data)
|
||||
{
|
||||
os_iter *itr;
|
||||
os_threadCleanup *obj;
|
||||
os_iter *itr;
|
||||
os_threadCleanup *obj;
|
||||
|
||||
assert(func != NULL);
|
||||
assert (func != NULL);
|
||||
|
||||
(void)pthread_once(&cleanup_once, &os_threadCleanupInit);
|
||||
itr = (os_iter *)pthread_getspecific(cleanup_key);
|
||||
if (itr == NULL) {
|
||||
itr = os_iterNew();
|
||||
assert(itr != NULL);
|
||||
if (pthread_setspecific(cleanup_key, itr) == EINVAL) {
|
||||
DDS_WARNING("pthread_setspecific failed with error EINVAL (%d)\n", EINVAL);
|
||||
os_iterFree(itr, NULL);
|
||||
itr = NULL;
|
||||
}
|
||||
}
|
||||
(void) pthread_once (&cleanup_once, &os_threadCleanupInit);
|
||||
if ((itr = pthread_getspecific (cleanup_key)) == NULL)
|
||||
{
|
||||
int ret;
|
||||
itr = os_iterNew ();
|
||||
assert (itr != NULL);
|
||||
if ((ret = pthread_setspecific (cleanup_key, itr)) != 0)
|
||||
DDS_FATAL ("os_threadCleanupPush: pthread_setspecific failed with error %d\n", ret);
|
||||
}
|
||||
|
||||
if(itr) {
|
||||
obj = os_malloc(sizeof(*obj));
|
||||
obj->func = func;
|
||||
obj->data = data;
|
||||
os_iterAppend(itr, obj);
|
||||
}
|
||||
obj = os_malloc (sizeof (*obj));
|
||||
obj->func = func;
|
||||
obj->data = data;
|
||||
os_iterAppend (itr, obj);
|
||||
}
|
||||
|
||||
void
|
||||
os_threadCleanupPop(
|
||||
int execute)
|
||||
void os_threadCleanupPop (int execute)
|
||||
{
|
||||
os_iter *itr;
|
||||
os_threadCleanup *obj;
|
||||
os_iter *itr;
|
||||
|
||||
(void)pthread_once(&cleanup_once, &os_threadCleanupInit);
|
||||
if ((itr = (os_iter *)pthread_getspecific(cleanup_key)) != NULL) {
|
||||
obj = (os_threadCleanup *)os_iterTake(itr, -1);
|
||||
if (obj != NULL) {
|
||||
if (execute) {
|
||||
obj->func(obj->data);
|
||||
}
|
||||
os_free(obj);
|
||||
}
|
||||
(void) pthread_once (&cleanup_once, &os_threadCleanupInit);
|
||||
if ((itr = pthread_getspecific (cleanup_key)) != NULL)
|
||||
{
|
||||
os_threadCleanup *obj;
|
||||
if ((obj = os_iterTake (itr, -1)) != NULL)
|
||||
{
|
||||
if (execute)
|
||||
obj->func(obj->data);
|
||||
os_free(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,10 +350,6 @@ CU_Test(dds_log, synchronous_sink_changes)
|
|||
os_mutexLock(&mutex);
|
||||
dds_set_log_sink(&block, &arg);
|
||||
os_threadAttrInit(&tattr);
|
||||
#ifdef __APPLE__
|
||||
tattr.schedPriority = sched_get_priority_min(SCHED_OTHER);
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
res = os_threadCreate(&tid, "foobar", &tattr, &run, &arg);
|
||||
CU_ASSERT_EQUAL_FATAL(res, os_resultSuccess);
|
||||
os_condWait(&cond, &mutex);
|
||||
|
|
|
@ -70,11 +70,6 @@ uint32_t threadMemory_thread (_In_opt_ void *args)
|
|||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for child thread for index already in use */
|
||||
printf("Starting os_threadMemMalloc_004\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemGet for child thread and non allocated index */
|
||||
printf("Starting os_threadMemGet_003\n");
|
||||
returnval = os_threadMemGet (OS_THREAD_WARNING);
|
||||
|
@ -638,24 +633,6 @@ CU_Test(os_thread, memmalloc)
|
|||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index already in use */
|
||||
printf ("Starting os_thread_memmalloc_002\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index < 0 */
|
||||
printf ("Starting os_thread_memmalloc_003\n");
|
||||
returnval = os_threadMemMalloc (-1, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index >= OS_THREAD_MEM_ARRAY_SIZE */
|
||||
printf ("Starting os_thread_memmalloc_004\n");
|
||||
returnval = os_threadMemMalloc (OS_THREAD_MEM_ARRAY_SIZE, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
printf ("Ending tc_thread_memmalloc\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue